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

Next Auth v5:如何传递自定义时区数据至JWT与Session回调

在NextAuth v5中登录时传递并存储用户时区到Session

方法一:通过Credentials提供者直接传递(适用于自定义登录逻辑)

如果你用的是Credentials登录提供者,可以直接在signIn调用中传递时区,然后在授权流程中存入JWT和Session:

  1. 自定义登录页面调用signIn时传入时区
    在客户端组件的登录逻辑里,获取当前用户时区并作为参数传入signIn:

    import { signIn } from '@/auth';
    
    const handleLogin = async () => {
      const userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
      await signIn('credentials', {
        email: userEmail,
        password: userPassword,
        timezone: userTimezone,
        redirect: true,
        callbackUrl: '/'
      });
    };
    
  2. 在Credentials提供者的authorize回调中接收时区
    在NextAuth配置里,定义Credentials提供者时,确保credentials包含timezone字段,并在authorize中获取该值,随用户数据一起返回:

    import NextAuth from 'next-auth';
    import Credentials from 'next-auth/providers/credentials';
    
    export const { handlers, auth, signIn, signOut } = NextAuth({
      providers: [
        Credentials({
          credentials: {
            email: { label: 'Email', type: 'email' },
            password: { label: 'Password', type: 'password' },
            timezone: { type: 'text' } // 声明时区字段
          },
          authorize: async (credentials) => {
            // 替换为你的用户验证逻辑
            const user = await validateUser(credentials.email, credentials.password);
            if (!user) return null;
    
            // 返回包含时区的用户数据
            return {
              id: user.id,
              email: user.email,
              name: user.name,
              timezone: credentials.timezone
            };
          }
        })
      ],
      callbacks: {
        // 将时区存入JWT
        async jwt({ token, user }) {
          if (user) {
            token.timezone = user.timezone;
          }
          return token;
        },
        // 将时区同步到Session
        async session({ session, token }) {
          session.user.timezone = token.timezone;
          return session;
        }
      }
    });
    

方法二:登录后通过API更新(适用于OAuth或无法直接传递的场景)

如果使用OAuth提供者(如Google、GitHub),无法直接在signIn时传递自定义参数,可以登录后通过API将时区存入数据库,再同步到Session:

  1. 客户端登录成功后调用API保存时区
    在登录后的客户端组件中,获取时区并调用自定义API路由:

    import { useSession } from '@/auth';
    
    const PostLogin = () => {
      const { update } = useSession();
    
      useEffect(() => {
        const saveTimezone = async () => {
          const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
          await fetch('/api/save-timezone', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ timezone })
          });
          // 更新Session以获取最新的时区数据
          await update();
        };
    
        saveTimezone();
      }, [update]);
    
      return <div>登录成功,正在同步时区...</div>;
    };
    
  2. 编写API路由处理时区存储
    创建app/api/save-timezone/route.js,验证用户身份后将时区存入数据库:

    import { auth } from '@/auth';
    import prisma from '@/lib/prisma';
    
    export async function POST(req) {
      const session = await auth();
      if (!session?.user?.id) {
        return new Response('Unauthorized', { status: 401 });
      }
    
      const { timezone } = await req.json();
      await prisma.user.update({
        where: { id: session.user.id },
        data: { timezone }
      });
    
      return new Response('OK', { status: 200 });
    }
    
  3. 在Session回调中从数据库获取时区
    修改NextAuth配置的session回调,从数据库读取时区并同步到Session:

    callbacks: {
      async session({ session, token }) {
        if (token.sub) {
          const user = await prisma.user.findUnique({
            where: { id: token.sub },
            select: { timezone: true }
          });
          if (user) {
            session.user.timezone = user.timezone;
          }
        }
        return session;
      }
    }
    

注意事项

  • 确保使用NextAuth v5的正确API,v5的配置方式与v4略有不同(比如直接导出handlers、auth等)。
  • 时区可以通过Intl.DateTimeFormat().resolvedOptions().timeZone获取标准的IANA时区字符串(如Asia/Shanghai)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 11:43:19