I am having issues with storing a jwt token in my localstorage. I am using nextjs with typescript. In my backend with nodejs my token is stored correctly in a cookie.
In my previous apps with Reactjs I´ve used the following function:
import axios from 'axios';
axios.interceptors.request.use(
(config) => {
const token = localStorage.getItem("token");
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
export default setAuthToken;
But I´ve encountered my self with the issue that nextjs cannot handle this from the client.
This is my loadUser method in my authSlice where I want to set my token:
const apiUrl = configApi.apiUrl;
const initialState: AuthState = {
token: typeof window !== "undefined" ? localStorage.getItem("token") : null,
isAuthenticated: false,
isLoading: false,
user: null,
error: null,
};
function isTokenExpired(token: string | null): boolean {
try {
if (token) {
const decoded = jwtDecode(token) as { exp?: any } | undefined;
return decoded?.exp ? decoded.exp < Date.now() / 1000 : true;
}
return true;
} catch (e) {
return true;
}
}
export const loadUser = createAsyncThunk<
User,
void,
{ rejectValue: CustomError }
>("auth/loadUser", async (_, { rejectWithValue }) => {
try {
const token = localStorage.getItem("token");
if (token) {
if (isTokenExpired(token)) {
localStorage.removeItem("token");
} else {
setAuthToken(token);
}
}
const res = await axios.get<User>(`${apiUrl}:5000/api/v1/auth/me`);
return res.data;
} catch (error) {
return rejectWithValue({
message: (error as CustomError).message || "Unknown error",
status: (error as CustomError).status,
error: (error as CustomError).error,
});
}
});
Continues with the following:
export const authSlice = createSlice({
name: "auth",
initialState,
reducers: {
logout: (state) => {
localStorage.removeItem("token");
state.token = null;
state.isAuthenticated = false;
state.user = null;
},
},
extraReducers: (builder) => {
builder
.addCase(loadUser.pending, (state) => {
state.isLoading = true;
})
.addCase(loadUser.fulfilled, (state, action: PayloadAction<User>) => {
state.isLoading = false;
state.isAuthenticated = true;
state.user = action.payload;
})
.addCase(loadUser.rejected, (state, action) => {
state.isLoading = false;
state.isAuthenticated = false;
state.error = action.payload
? action.payload
: { message: "Unknown error" };
})
},
});
How can I store my token in my client with nextjs?