How to set my jwt token in my client/localstorage?

21 Views Asked by At

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?

0

There are 0 best solutions below