如何使用nextJS管理localStorage?

dar*_*dka 2 reactjs next.js

通常我使用 Django 和 React 制作应用程序,使用 JWT 进行身份验证。我正在测试nextJS。我无法管理 JWT 身份验证,因为我无法访问本地存储来获取我的 2 个令牌(访问+刷新)。

在 React 中,我使用 axios.js:

import axios from 'axios';
import { baseURL } from './const/urls';

const axiosInstance = axios.create({
  baseURL: baseURL,
  timeout: 5000,
  headers: {
    Authorization: localStorage.getItem('access_token')
      ? 'JWT ' + localStorage.getItem('access_token')
      : null,
    'Content-Type': 'application/json',
    accept: 'application/json',
    'Cache-Control': 'no-cache',
    Pragma: 'no-cache',
    Expires: '0'
  }
});

axiosInstance.interceptors.response.use(
  (response) => response,
  (error) => {
    const originalRequest = error.config;

    // Prevent infinite loops
    if (
      error.response.status === 401 &&
      originalRequest.url === '/token/refresh/'
    ) {
      window.location.href = '/login/';
      return Promise.reject(error);
    }

    if (
      error.response.data.code === 'token_not_valid' ||
      error.response.status === 401 ||
      error.response.statusText === 'Unauthorized'
    ) {
      const refreshToken = localStorage.getItem('refresh_token');

      if (refreshToken) {
        const tokenParts = JSON.parse(atob(refreshToken.split('.')[1]));

        // exp date in token is expressed in seconds, while now() returns milliseconds:
        const now = Math.ceil(Date.now() / 1000);

        if (tokenParts.exp > now) {
          return axiosInstance
            .post('/token/refresh/', { refresh: refreshToken })
            .then((response) => {
              localStorage.setItem('access_token', response.data.access);
              localStorage.setItem('refresh_token', response.data.refresh);

              axiosInstance.defaults.headers['Authorization'] =
                'JWT ' + response.data.access;
              originalRequest.headers['Authorization'] =
                'JWT ' + response.data.access;

              return axiosInstance(originalRequest);
            })
            .catch((err) => {
              console.log(err);
            });
        } else {
          console.log('Refresh token is expired', tokenParts.exp, now);
          window.location.href = '/Login/';
        }
      } else {
        console.log('Refresh token not available.');
        window.location.href = '/Login/';
      }
    }

    // specific error handling done elsewhere
    return Promise.reject(error);
  }
);

export default axiosInstance;
Run Code Online (Sandbox Code Playgroud)

但它不适用于 nextJS。localStorage 或 window.localStorage 未定义。我知道它不起作用,因为它尝试在服务器端执行代码。如何强制它仅使用客户端代码?我看到我可以 useEffect 但我不明白如何在我的情况下使用它。

Dor*_*ing 7

使用(typeof window === 'undefined')条件检查您是否可以访问在客户端可以但在服务器端无法访问的窗口。我经常使用它,所以它有效。例如,您可以根据条件检查执行类似的操作:

// save to storage
export const saveToStorage = (key, value) => {
    if(typeof window !== 'undefined') {
        return window.localStorage.setItem(key, value);
    }
}

// get from storage
export const getFromStorage = (key) => {
    if (typeof window !== 'undefined') {
        return window.localStorage.getItem(key);
    }
}
Run Code Online (Sandbox Code Playgroud)