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

如何在Auth.js(NextAuth v5)中正确实现10秒令牌过期功能?

实现NextAuth v5中10秒令牌过期的测试功能

我正在开发一个使用NextAuth(v5)进行身份验证的Next.js项目,希望为测试目的实现10秒的令牌过期功能。目标是用户登录后可在10秒内访问受保护路由,令牌过期后刷新页面或导航时需重定向至登录页。

当前实现代码

auth.ts

import NextAuth from "next-auth"
import authConfig from "@/auth.config"
 
export const { handlers, signIn, signOut, auth } = NextAuth({
  ...authConfig,
  pages: {
    signIn: '/sign-in'
  },
  session: {
    strategy: "jwt",
    // maxAge: <number>,
    // updateAge: <number>,
  },
  callbacks: {
    async jwt({ token, user }) {
      console.log('\n hello from jwt callback. \n'); // DEBUG
      if (user){
        token.firstName = user.firstName;
        token.lastName = user.lastName;
        token.email = user.email;
      }
      return token;
    },

    async session({ session, token }) {
      console.log('\n hello from session callback. \n'); // DEBUG
      session.user.firstName = token.firstName as string;
      session.user.lastName = token.lastName as string;
      session.user.email = token.email as string; 
      return session;
    },
  },
});

middleware.ts

import authConfig from "@/auth.config"
import NextAuth from "next-auth"
import { NextResponse } from "next/server";

const { auth: middleware } = NextAuth(authConfig);

export default  middleware( async (req) => {
  const url = req.nextUrl.clone();
  if(url.pathname.startsWith('/api/auth')) return NextResponse.next();
  if(url.pathname.startsWith('/api/users')) return NextResponse.next();

  const isLoggedIn = !!req.auth;

  if(!isLoggedIn){
    if(url.pathname.startsWith('/api')){ 
      return NextResponse.json(
        { message: "Unauthorized" },
        { status: 401 } 
      );
    }else{
      url.pathname = '/sign-in'
      return NextResponse.redirect(url);
    }
  }
  return NextResponse.next();
})
 
export const config = {
  matcher: [
    "/((?!.*\\.[\\w]+$|_next|sign-in|sign-up).*)", // Match all paths except static files, `_next`, `sign-in` and `sign-up` paths
    "/",                           // Root route
    "/api/:path*",                 // API routes
    "/trpc/:path*",                // TRPC routes
  ],
};

已尝试的方法

  • 在session: { strategy: "jwt", ...}下配置maxAge等参数,期望令牌10秒后过期,但令牌过期规则未按预期生效,客户端仍可在10秒后访问受保护路由。

预期行为

  • 用户登录后可在10秒内访问路由。
  • 10秒后令牌过期,用户刷新页面或导航时会被重定向至登录页。

注意:本实现基于NextAuth v5(当前最新版本),部分概念和API(如令牌处理和会话管理)与旧稳定版(如v4)不同。


解决方案

在NextAuth v5中,要实现JWT令牌的10秒过期,需要从以下几个方面调整配置:

1. 配置JWT与会话的过期时间

在auth.ts的NextAuth配置中,需同时设置session.maxAge和jwt.maxAge,并在session回调中同步会话过期时间:

export const { handlers, signIn, signOut, auth } = NextAuth({
  ...authConfig,
  pages: {
    signIn: '/sign-in'
  },
  session: {
    strategy: "jwt",
    maxAge: 10, // 会话最大存活时间(秒)
  },
  jwt: {
    maxAge: 10, // JWT令牌过期时间(秒)
  },
  callbacks: {
    async jwt({ token, user }) {
      console.log('\n hello from jwt callback. \n'); // DEBUG
      if (user){
        token.firstName = user.firstName;
        token.lastName = user.lastName;
        token.email = user.email;
      }
      return token;
    },

    async session({ session, token }) {
      console.log('\n hello from session callback. \n'); // DEBUG
      session.user.firstName = token.firstName as string;
      session.user.lastName = token.lastName as string;
      session.user.email = token.email as string; 
      // 同步会话过期时间与JWT
      session.expires = new Date(Date.now() + 10 * 1000).toISOString();
      return session;
    },
  },
});

2. 修正middleware的会话验证逻辑

NextAuth v5中auth是异步函数,需调用后获取会话;可手动校验会话过期时间增强可靠性:

export default middleware(async (req) => {
  const url = req.nextUrl.clone();
  if(url.pathname.startsWith('/api/auth')) return NextResponse.next();
  if(url.pathname.startsWith('/api/users')) return NextResponse.next();

  const session = await req.auth(); // v5中需调用auth()获取会话
  const isLoggedIn = !!session;

  if(!isLoggedIn){
    if(url.pathname.startsWith('/api')){ 
      return NextResponse.json(
        { message: "Unauthorized" },
        { status: 401 } 
      );
    }else{
      url.pathname = '/sign-in'
      return NextResponse.redirect(url);
    }
  }

  // 可选:手动校验会话是否过期
  if(session?.expires && new Date(session.expires) < new Date()){
    if(url.pathname.startsWith('/api')){
      return NextResponse.json({ message: "Session expired" }, { status: 401 });
    }else{
      url.pathname = '/sign-in';
      return NextResponse.redirect(url);
    }
  }

  return NextResponse.next();
})

关键说明

  • NextAuth v5中session.maxAge控制会话生命周期,jwt.maxAge控制JWT本身过期时间,两者需保持一致才能生效。
  • 在session回调中手动设置session.expires,可让客户端感知会话过期时间,提升体验。
  • 必须调用await req.auth()获取会话对象,而非直接访问req.auth,这是v5的API变化点。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 01:31:01