You need to enable JavaScript to run this app. NextAuth.js 向Session添加额外属性:Discord认证会话异常问题
优惠活动
大模型
产品
解决方案
定价
更多

NextAuth.js 向Session添加额外属性:Discord认证会话异常问题

问题根因
  • Cookie大小超限导致登录态丢失:使用JWT会话策略(NextAuth无适配器时的默认策略)时,完整JWT会序列化后存入客户端Cookie。你把包含全量Discord guilds数组的profile直接塞进JWT后,整体体积极易超过浏览器单Cookie 4KB的限制,浏览器会直接丢弃超限Cookie,导致NextAuth每次请求都无法获取有效登录态,表现为会话返回null、反复跳转Discord要求重新授权。
  • 类型报错未做扩展定义:NextAuth内置的Session、JWT类型仅包含基础字段,你新增的profile、accessToken、自定义guilds字段未在TS类型声明中扩展,因此触发类型校验报错,不需要额外用@ts-ignore规避。
修正实现步骤

1. 优化存储逻辑,规避Cookie超限

根据guilds的使用场景选择对应方案:

  • 若guilds仅需在部分页面使用:仅在JWT中存储accessToken,需要guilds时在服务端接口中用accessToken实时请求Discord接口拉取,不要将全量guilds存入客户端。
  • 若需要全局直接访问guilds:优先过滤guilds字段,仅保留必要属性(如id、name),减少存储体积;如果guilds数量过多(体积仍超限),则切换为数据库会话策略,将会话内容存在服务端数据库,客户端Cookie仅存储会话ID,完全不受Cookie大小限制。
  • 注意:Discord v8 API已废弃,建议替换为v10版本的接口地址。

2. 修正回调逻辑

修正后的JWT回调

仅在初次登录时写入自定义字段,过滤冗余内容:

async jwt(token, user, account, profile, isNewUser) {
  // 仅初次登录时写入自定义数据,后续回调profile参数为undefined
  if (user && account?.access_token) {
    token.accessToken = account.access_token;
    // 仅保留需要的Discord profile字段,避免冗余
    token.profile = {
      id: profile.id,
      username: profile.username,
      email: profile.email,
    };

    // 拉取guilds并过滤冗余字段
    const guildRes = await fetch("https://discord.com/api/v10/users/@me/guilds", {
      headers: {
        Authorization: `Bearer ${account.access_token}`,
      },
    });
    const rawGuilds = await guildRes.json();
    // 过滤后仅存必要属性,压缩体积
    token.profile.guilds = rawGuilds.map(g => ({ id: g.id, name: g.name }));
  }
  return token;
}

修正后的Session回调

直接从token中读取自定义字段赋值到会话即可:

async session(session, token) {
  session.accessToken = token.accessToken;
  session.profile = token.profile;
  return session;
}

3. 彻底解决TS类型报错

不需要使用@ts-ignore,通过扩展NextAuth的内置类型实现类型提示:
在项目根目录新建types/next-auth.d.ts类型声明文件,写入以下内容:

import NextAuth, { DefaultSession } from "next-auth";

// 扩展Session类型
declare module "next-auth" {
  interface Session {
    accessToken?: string;
    profile?: {
      id: string;
      username: string;
      email?: string;
      guilds?: Array<{ id: string; name: string }>;
    } & DefaultSession["user"];
  }
}

// 扩展JWT类型
declare module "next-auth/jwt" {
  interface JWT {
    accessToken?: string;
    profile?: Session["profile"];
  }
}

确保该类型文件被tsconfig.json的include字段扫描到,即可消除所有类型报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.25 12:36:03