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

NextAuth结合Auth0认证:Session回调中无法获取Token求助

解决方案

问题分析

核心问题出在两处:

  1. jwt回调未完整存储用户信息与Token有效期,导致后续session回调无法从token中拿到有效数据;
  2. signIn回调的参数结构错误,误将profile作为第一个参数,实际该回调接收的是包含user、account等属性的对象,导致Token判断逻辑出错。

修复步骤

1. 完善jwt回调,持久化Token与用户信息

jwt回调是Token逻辑的核心,需在首次登录时存储access_token、用户信息及过期时间,同时处理Token有效期判断:

async jwt({ token, user, account, profile }) {
  // 首次授权成功,存储核心数据
  if (account && user) {
    return {
      accessToken: account.access_token,
      user: {
        id: profile.sub,
        name: profile.name,
        email: profile.email
        // 按需添加其他用户字段
      },
      expiresAt: account.expires_at * 1000 // 转换为毫秒时间戳,方便过期判断
    };
  }
  // Token未过期则直接返回
  if (Date.now() < token.expiresAt) {
    return token;
  }
  // 可在此添加Token刷新逻辑(若Auth0配置了刷新Token)
  return token;
}

2. 修正signIn回调的参数结构

调整参数为正确的对象解构,才能准确获取account.access_token:

async signIn({ user, account, profile }) {
  if (account?.access_token) {
    console.log('ACCESS TOKEN!!!!!!!:', account.access_token);
    return '/apps';
  }
  return true;
}

3. 确保session回调正确映射数据

原session回调逻辑本身没问题,但需依赖修正后的jwt回调提供完整的token数据:

session: async ({ session, token }) => {
  if (token) {
    session.user = token.user;
    session.accessToken = token.accessToken;
    session.error = token.error;
  }
  return session;
}

前端获取Token并携带到API请求

修改完成后,可通过useSession钩子在前端获取accessToken并携带到请求头:

import { useSession } from 'next-auth/react';

// 组件内使用
const { data: session } = useSession();

// 发起API请求示例
const fetchData = async () => {
  if (!session?.accessToken) return;
  
  const res = await fetch('/api/your-api', {
    headers: {
      'Authorization': `Bearer ${session.accessToken}`
    }
  });
  const data = await res.json();
};

完整修正后的[...nextauth].js代码

import NextAuth from 'next-auth';
import Auth0Provider from 'next-auth/providers/auth0';

export default NextAuth({
  providers: [
    Auth0Provider({
      clientId: 'pF....H',
      clientSecret: 'Mh.....vAbQ',
      issuer: 'https://dev-xceoh....8u8.us.auth0.com',
      redirectUri: `http://localhost:3000/api/auth/callback/auth0`,
      idToken: true,
      token: {
        params: {
          audience: 'https://dev-xce.....r8u8.us.auth0.com/api/v2/'
        }
      },
      authorization: {
        params: {
          audience: encodeURI('https://dev-x......r8u8.us.auth0.com/api/v2/')
        }
      }
    }),
  ],
  secret: '306.................024',
  session: {
    strategy: 'jwt',
    secret: process.env.NEXTAUTH_SECRET
  },
  jwt: {},
  callbacks: {
    session: async ({ session, token }) => {
      if (token) {
        session.user = token.user;
        session.accessToken = token.accessToken;
        session.error = token.error;
      }
      return session;
    },
    async redirect(url) {
      if (typeof url === 'string') {
        return url.startsWith('http://localhost:3000') ? url : 'http://localhost:3000';
      } else {
        return 'http://localhost:3000';
      }
    },
    async jwt({ token, user, account, profile }) {
      if (account && user) {
        return {
          accessToken: account.access_token,
          user: {
            id: profile.sub,
            name: profile.name,
            email: profile.email,
          },
          expiresAt: account.expires_at * 1000,
        };
      }
      if (Date.now() < token.expiresAt) {
        return token;
      }
      return token;
    },
    async signIn({ user, account, profile }) {
      if (account?.access_token) {
        console.log('ACCESS TOKEN!!!!!!!:', account.access_token);
        return '/apps';
      }
      return true;
    },
  },
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 02:35:03