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

如何在Next-Auth中使用自定义后端JWT?

在Next-Auth中使用自定义后端JWT的实现方案

问题概述

使用CredentialsProvider登录时,Next-Auth会自动生成next-auth.session-token作为会话凭证,而非直接使用后端返回的access_token。同时存在NEXTAUTH_SECRET相关错误,需要替换默认Token为自定义后端JWT。

原代码问题

原代码仅将后端Token合并到Next-Auth的默认JWT结构中,并未覆盖Next-Auth的Token生成逻辑,因此cookie中仍然是Next-Auth自行生成的Token。

解决方案

1. 覆盖JWT编码/解码逻辑

通过配置jwt选项的encode和decode方法,直接使用后端返回的Token作为会话凭证:

  • encode方法直接返回后端access_token,替代Next-Auth生成的Token
  • decode方法解析后端Token,供会话回调使用

2. 修正回调逻辑

调整jwt和session回调,确保会话中携带的是自定义Token和用户信息

3. 解决NEXTAUTH_SECRET错误

在.env.local中添加NEXTAUTH_SECRET,可通过openssl rand -hex 32生成安全密钥

修改后的完整代码

import type { NextAuthOptions } from 'next-auth'
import CredentialsProvider from 'next-auth/providers/credentials'
import decode from "jwt-decode";

import loginService from "@/services/auth";

export const options: NextAuthOptions = {
  providers: [
    CredentialsProvider({
      name: "Credentials",
      credentials: {
        email: { label: "Email", type: "email", placeholder: "Email" },
        password: { label: "Password:", type: "password", placeholder: "Password" }
      },
      async authorize(credentials) {
        const email = credentials?.email || "";
        const password = credentials?.password || "";
        try {  
          const loginRes = await loginService.login(email, password);
          if (!loginRes?.access_token) return null;
          
          // 解析Token获取用户ID,用于会话标识
          const decodedToken = decode(loginRes.access_token) as { user_id: string };
          return { id: decodedToken.user_id, token: loginRes.access_token };
        } catch {
          return null;
        } 
      }
    })
  ],
  session: {
    strategy: "jwt",
    // 禁用Next-Auth的会话过期管理,依赖后端Token的过期时间
    maxAge: 0,
  },
  jwt: {
    secret: process.env.NEXTAUTH_SECRET,
    // 直接返回后端Token作为会话凭证
    async encode({ token }) {
      return token.token as string;
    },
    // 解析后端Token并返回完整结构
    async decode({ token }) {
      const decoded = decode(token as string) as { user_id: string };
      return { id: decoded.user_id, token: token };
    },
  },
  callbacks: {
    async jwt({ token, user }) {
      // 登录时直接返回用户对象(包含后端Token)
      return user ? user : token;
    },
    async session({ session, token }) {
      // 将自定义Token和用户ID挂载到会话中
      session.user.id = token.id;
      session.accessToken = token.token;
      return session;
    },
  },
  pages: {
    signIn: `${process.env.NEXTAUTH_URL}/login` 
  }
};

关键说明

  • next-auth.session-token cookie现在会存储后端返回的access_token
  • 会话过期由后端Token的过期时间决定,Next-Auth不再自动刷新会话
  • 必须配置NEXTAUTH_SECRET,否则会出现签名验证错误

内容的提问来源于stack exchange,提问作者Juancho Plass Cedillo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 12:03:32