You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next-Auth:getServerSideProps调用的API中间件中getToken获AccessToken返回undefined

问题解答

这种情况是正常的,核心原因在于服务器端内部发起的HTTP请求不会自动携带用户的会话Cookie,而NextAuth的getToken函数正是依赖请求中的Cookie来解析出accessToken。

具体原因

当你在getServerSideProps里通过axios.get()调用自己的API路由时,这个请求是服务器到服务器的内部请求,并非来自用户浏览器。这类请求不会自动附带用户浏览器发送过来的NextAuth会话Cookie(比如next-auth.session-token)。而getServerSideProps能正常获取accessToken,是因为它直接接收了来自浏览器的完整请求,包含所有用户Cookie信息。

解决方案

针对这个问题,有两种常用的处理方式:

方案1:在getServerSideProps中获取Token,通过请求头传递给API路由

先在getServerSideProps中拿到accessToken,再通过请求头传递给API路由,避免API路由依赖Cookie获取Token。

修改pages/user.js:

import { getToken } from "next-auth/jwt";

function User({user_data, request_params}) {
   // ...组件逻辑
}

export default User;

export async function getServerSideProps( context ) {
    // 先在getServerSideProps中获取Token
    const token = await getToken({ req: context.req, secret: process.env.SECRET });
    const user_data = await fetchUserData( context.query, token.accessToken );

    return {
        props: {
            user_data: user_data,
            request_params: context.query
        }
    }
}

async function fetchUserData( params, accessToken ) {
    const ajax_url = 'http://localhost:3000/api/user/1/info';

    let result;
    await axios.get(ajax_url, {
        headers: {
            // 将Token通过Authorization头传递
            'Authorization': `Bearer ${accessToken}`
        }
    })
    .then(response => {
        result = response.data;
    }).catch((error) => {
        // 原错误处理逻辑不变
        if (error.response) {
            console.log('Error.response > Data: ', error.response.data);
            console.log('Error.response > Status: ', error.response.status);
            console.log('Error.response > Headers: ', error.response.headers);
        } else if (error.request) {
            console.log('Error.request: ', error.request);
        } else {
            console.log('Error: ', error.message);
        }
        console.log('Unknown Error: ', error.config);
    });

    return result;
}

修改api/user/[user]/info.js:

import axios from "axios";

export default async (req, res) => {
    // 从请求头中直接获取Token
    const authHeader = req.headers.authorization;
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
        return res.status(401).json({ error: 'Unauthorized' });
    }
    const accessToken = authHeader.split(' ')[1];

    console.log('access token?: ' + accessToken); // 现在能正常获取到Token

    const config = {
        headers: {
            'authorization': `Bearer ${accessToken}`,
            'Cache-Control': 'no-cache',
            'Pragma': 'no-cache',
            'Expires': '0',
        }
    };

    const ajax_url = `http://localhost/actualwebsite/public/api/v1/user/${req.query.user}/info`;

    await axios.get(ajax_url, config)
    .then(response => {
        res.setHeader('Cache-Control', 'no-cache');
        res.setHeader('Expires', '0');
        res.status(200).json(response.data);
    }).catch((error) => {
        // 原错误处理逻辑不变
        if (error.response) {
            console.log('Api > Error.response > Data: ', error.response.data);
            console.log('Api > Error.response > Status: ', error.response.status);
            console.log('Api > Error.response > Headers: ', error.response.headers);
        } else if (error.request) {
            console.log('Api > Error.request: ', error.request);
        } else {
            console.log('Api > Error: ', error.message);
        }
        console.log('Api > Unknown Error: ', error.config);
    });
}

方案2:直接在getServerSideProps中调用外部API(更高效)

跳过内部API路由,直接在getServerSideProps中完成外部API请求,减少一次服务器内部HTTP调用:

import { getToken } from "next-auth/jwt";
import axios from "axios";

function User({user_data, request_params}) {
   // ...组件逻辑
}

export default User;

export async function getServerSideProps( context ) {
    const token = await getToken({ req: context.req, secret: process.env.SECRET });
    const { user } = context.query;

    const ajax_url = `http://localhost/actualwebsite/public/api/v1/user/${user}/info`;
    const config = {
        headers: {
            'authorization': `Bearer ${token.accessToken}`,
            'Cache-Control': 'no-cache',
            'Pragma': 'no-cache',
            'Expires': '0',
        }
    };

    let user_data = null;
    try {
        const response = await axios.get(ajax_url, config);
        user_data = response.data;
    } catch (error) {
        // 错误处理逻辑
        if (error.response) {
            console.log('Error.response > Data: ', error.response.data);
            console.log('Error.response > Status: ', error.response.status);
            console.log('Error.response > Headers: ', error.response.headers);
        } else if (error.request) {
            console.log('Error.request: ', error.request);
        } else {
            console.log('Error: ', error.message);
        }
        console.log('Unknown Error: ', error.config);
    }

    return {
        props: {
            user_data: user_data,
            request_params: context.query
        }
    }
}

内容的提问来源于stack exchange,提问作者yeln

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 02:35:19