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

Next.js 14中如何将外部API返回的JWT存入Session?

如何将后端返回的JWT存入NextAuth Session并在客户端组件中便捷访问

当然可以把JWT存入NextAuth Session,这不仅能解决你当前客户端组件难以获取令牌的问题,还能简化认证流程。以下是具体的实现步骤和代码调整方案:

核心思路

NextAuth的jwt和session回调就是用来扩展认证信息的,我们可以把后端返回的JWT令牌(access_token、refresh_token)存入NextAuth的JWT中,再同步到Session,这样客户端组件就能通过useSession钩子直接获取,无需手动传递参数。

代码调整步骤

1. 修改authorize函数,移除手动设置Cookie的逻辑

原来的代码里手动设置了gat和grt Cookie,现在可以去掉这部分,把后端返回的令牌和用户信息一起返回即可,NextAuth会自动处理JWT的存储:

async authorize(credentials) {
  const { username, password } = credentials as {
    username: string;
    password: string;
  };
  
  const formData = new URLSearchParams();
  formData.append("email", encodeURIComponent(username));
  formData.append("password", encodeURIComponent(password));

  const res = await fetch(loginPath, {
    method: "POST",
    headers: {
      "Content-Type": "application/x-www-form-urlencoded",
    },
    body: formData.toString(),
  });
  const receivedToken = await res.json();
  
  if (res.ok && receivedToken) {
    const parsed = parsePayload(receivedToken.access_token);
    // 整理要返回的用户信息,包含令牌和解析后的用户数据
    return {
      id: parsed.sub, // 假设JWT payload里有用户ID
      name: parsed.name,
      email: username,
      access_token: receivedToken.access_token,
      refresh_token: receivedToken.refresh_token,
      expires_at: parsed.exp // 可选,存入过期时间
    };
  } else {
    return null;
  }
}

2. 完善jwt回调,合并令牌信息到NextAuth的JWT

不要直接替换token,而是把用户返回的信息合并进去,避免丢失NextAuth默认的token字段:

jwt: async ({ token, user }) => {
  // 用户登录时,把后端返回的信息合并到token
  if (user) {
    token.id = user.id;
    token.name = user.name;
    token.email = user.email;
    token.access_token = user.access_token;
    token.refresh_token = user.refresh_token;
    token.expires_at = user.expires_at;
  }
  return token;
},

3. 调整session回调,将令牌同步到Session

把JWT中的令牌信息放到session对象里,这样客户端就能获取:

session: async ({ session, token }) => {
  session.user.id = token.id;
  session.user.name = token.name;
  session.user.email = token.email;
  // 把令牌添加到session,客户端可访问
  session.access_token = token.access_token;
  session.refresh_token = token.refresh_token;
  session.expires_at = token.expires_at;
  return session;
},

4. 客户端组件中获取令牌

现在可以直接用NextAuth的useSession钩子在客户端组件中获取令牌,无需从服务器组件传递:

"use client";

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

export default function ClientComponent() {
  const { data: session, status } = useSession();

  if (status === "loading") {
    return <div>加载中...</div>;
  }

  if (!session) {
    return <div>请先登录</div>;
  }

  // 直接使用session中的令牌
  console.log("Access Token:", session.access_token);

  return (
    <div>
      <p>欢迎,{session.user.name}</p>
    </div>
  );
}

可选:保留httpOnly Cookie用于后端API调用

如果你仍需要将access_token存为httpOnly Cookie(比如后端API直接验证Cookie),可以在jwt回调中设置Cookie,同时存入Session:

import { cookies } from "next/headers";

// 在jwt回调中添加
jwt: async ({ token, user }) => {
  if (user) {
    // ... 之前的合并逻辑
    // 设置httpOnly Cookie
    cookies().set({
      name: "gat",
      value: user.access_token,
      httpOnly: true,
      secure: process.env.NODE_ENV === "production",
      sameSite: "strict",
      path: "/",
    });
    cookies().set({
      name: "grt",
      value: user.refresh_token,
      httpOnly: true,
      secure: process.env.NODE_ENV === "production",
      sameSite: "strict",
      path: "/",
    });
  }
  return token;
},

为什么这是更优方案

  • 客户端组件无需依赖服务器组件传递令牌,代码更简洁
  • 利用NextAuth的Session管理机制,自动处理会话的持久化和刷新(可扩展refresh_token的自动刷新逻辑)
  • 统一认证信息的存储,避免手动管理Cookie的繁琐和潜在错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 03:23:36