解决Next Auth getSession()返回空值导致Axios授权头异常问题
你的方案没奏效主要有两个核心问题:
useState的更新是异步的,当status变为authenticated时,accessToken可能还没从data?.user.accessToken同步过来,此时返回的axios实例里Authorization头还是Bearer undefined。- 当
status不是authenticated时,Hook没有返回值,这会导致调用这个Hook的组件直接抛出错误。
下面是修正后的实现思路和代码:
优化方案1:直接使用session中的accessToken,去掉多余的useState
既然useSession的data已经包含了accessToken,没必要额外用useState存储,直接读取即可避免异步更新的延迟问题:
import axios from 'axios'; import { useSession } from 'next-auth/react'; // 按实际使用的会话库调整 export const useAxiosPrivate = () => { const { data: session, status } = useSession(); const accessToken = session?.user.accessToken; // 创建基础axios实例 const axiosPrivate = axios.create({ baseURL: `${SERVER_LOCALHOST}/api/v1`, headers: { 'Content-Type': 'application/json', }, }); // 请求拦截器:发送请求前动态注入有效token axiosPrivate.interceptors.request.use( (config) => { if (!config.headers['Authorization'] && accessToken) { config.headers['Authorization'] = `Bearer ${accessToken}`; } return config; }, (error) => Promise.reject(error) ); // 未认证时拦截所有请求 if (status !== 'authenticated') { axiosPrivate.interceptors.request.use(() => { return Promise.reject(new Error('用户未完成认证')); }); } return axiosPrivate; };
优化方案2:确保accessToken同步后再返回可用实例
如果坚持要用useState存储accessToken,可以通过useEffect监听会话状态,确保token有效时再创建实例:
import axios from 'axios'; import { useSession } from 'next-auth/react'; import { useState, useEffect } from 'react'; export const useAxiosPrivate = () => { const { data: session, status } = useSession(); const [axiosPrivate, setAxiosPrivate] = useState(null); useEffect(() => { if (status === 'authenticated' && session?.user.accessToken) { const instance = axios.create({ baseURL: `${SERVER_LOCALHOST}/api/v1`, headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${session.user.accessToken}`, }, }); setAxiosPrivate(instance); } else { setAxiosPrivate(null); } }, [session, status]); return axiosPrivate; };
使用这个Hook时需要先判断实例是否存在:
const axiosPrivate = useAxiosPrivate(); if (!axiosPrivate) { // 处理未认证逻辑,比如跳转登录页 return <div>请先登录</div>; } // 正常发送请求 axiosPrivate.get('/protected/resource');
关键注意点
- 禁止在Hook中出现条件返回导致的未定义返回值,始终确保有明确返回(实例、null或错误)。
- 用axios拦截器处理请求头注入比创建实例时硬编码更灵活,能避免token更新不及时的问题。
- 直接从会话对象读取token比额外用状态存储更高效,消除异步更新的延迟隐患。
内容的提问来源于stack exchange,提问作者slinger
相关产品推荐
相关产品推荐

