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

NextAuth:如何在客户端获取未解码的JWT会话令牌?

如何在Next.js客户端获取NextAuth未解码的原始JWT会话令牌?

我尝试从next-auth.session-token Cookie中直接获取会话令牌,但用了多个Cookie处理库都没能拿到值。另外,我也试过在构建session对象时把token和session一起传递,但得到的是解码后的令牌,不是原始的JWT文本。

我需要这个原始JWT令牌来向Hasura(通过URQL连接)发送认证请求。目前我用了个临时方案:创建/api/me接口来返回当前用户的令牌,代码如下:

import type { NextApiRequest, NextApiResponse } from "next";
import { getToken } from "next-auth/jwt";

export default async (req: NextApiRequest, res: NextApiResponse) => {
  const token = await getToken({ req, raw: true });

  res.status(200).json({ token });
};

然后通过这个接口的响应来实例化URQL客户端,但不想因为额外的请求浪费时间,请问有没有办法直接在客户端获取未解码的原始JWT令牌?


解决方法

方法1:通过NextAuth的回调直接返回原始令牌

在[...nextauth].ts配置文件中,修改jwt和session回调,把原始JWT令牌附加到会话对象中:

import NextAuth from "next-auth";
// 导入你的认证提供者,比如CredentialsProvider
import CredentialsProvider from "next-auth/providers/credentials";

export default NextAuth({
  providers: [
    // 你的认证提供者配置
    CredentialsProvider({
      // ... 你的具体配置逻辑
    }),
  ],
  // 必须启用JWT会话策略
  session: {
    strategy: "jwt",
  },
  callbacks: {
    async jwt({ token, account }) {
      // 登录时保存原始令牌(从account中获取)
      if (account?.accessToken) {
        token.raw = account.accessToken;
      }
      return token;
    },
    async session({ session, token }) {
      // 将原始令牌附加到返回给客户端的session对象
      session.rawToken = token.raw;
      return session;
    },
  },
});

之后在客户端通过useSession钩子就能直接拿到原始令牌:

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

const { data: session } = useSession();
const rawJwtToken = session?.rawToken;

方法2:直接读取Cookie(不推荐)

如果next-auth.session-token Cookie没有设置HttpOnly属性,客户端JS可以直接读取,但强烈不建议关闭HttpOnly——这会大幅增加XSS攻击风险,导致令牌被盗。如果一定要试,可使用以下代码:

function getCookie(name: string) {
  const value = `; ${document.cookie}`;
  const parts = value.split(`; ${name}=`);
  if (parts.length === 2) return parts.pop()?.split(';').shift();
}

const sessionToken = getCookie('next-auth.session-token');

方法3:URQL与NextAuth集成

用URQL的authExchange插件自动处理令牌传递,无需手动获取原始JWT:

import { createClient } from 'urql';
import { authExchange } from '@urql/exchange-auth';
import { getSession } from 'next-auth/react';

const client = createClient({
  url: '你的Hasura API端点',
  exchanges: [
    authExchange({
      async getAuth() {
        const session = await getSession();
        return session?.rawToken ? `Bearer ${session.rawToken}` : null;
      },
      addAuthToOperation(operation, authState) {
        if (!authState) return operation;
        return {
          ...operation,
          context: {
            ...operation.context,
            headers: {
              ...operation.context.headers,
              Authorization: authState,
            },
          },
        };
      },
    }),
  ],
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 00:21:41