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

使用NextAuth时auth.js v5的route.ts文件出现Session为Null的问题

Auth.js v5 API路由中无法获取Session(服务器组件正常)

问题描述

使用Auth.js v5时,API路由中调用auth()始终返回null,但相同的auth()函数在服务器组件中可正常获取session。需要通过session提取用户ID查询数据库,但API路由一直返回401未授权。

相关代码

route.ts

import { auth } from "@/auth";
import { db } from "@/lib/db";
import { NextRequest, NextResponse } from "next/server";

export async function GET(req: NextRequest) {
    try {
        const session = await auth();
        console.log(session, "session");
        
        if (!session) {
            return NextResponse.json({ user: null, message: 'Unauthorized' }, { status: 401 });
        }
        const id = Number(session?.user?.id);
        const user = await db.user.findUnique({
            where: { id }
        });
        if (!user) {
            return NextResponse.json({ user: null, message: 'User not found' }, { status: 404 });
        }
        const { password, ...userData } = user;
        return NextResponse.json({ user: userData, message: 'User found' }, { status: 200 });
    } catch (error: any) {
        return NextResponse.json({ error: error.message, message: "Something went wrong!" }, { status: 500 });
    }
}

auth.ts

import { PrismaAdapter } from "@auth/prisma-adapter";
import { PrismaClient } from "@prisma/client";
import NextAuth from "next-auth";
import authConfig from "./auth.config";
const prisma = new PrismaClient()

export const { handlers, auth, signIn, signOut } = NextAuth({
    adapter: PrismaAdapter(prisma),
    secret: process.env.AUTH_SECRET,
    session: { strategy: "jwt" },
    callbacks: {
        async session({ session, token }) {
            if (!token) {return session;}
            if (session.user && token.sub) {
                session.user.id = token.sub;}
            return session;
        },
        async jwt({ token, user }) {
            if (user) {
                token.id = user.id;
            }
            return token;}},
    ...authConfig,})

auth.config.ts

import { NextAuthConfig } from "next-auth";
import Credentials from "next-auth/providers/credentials";
import { db } from "./lib/db";
import { LoginSchema } from "./schemas/user-schema";
import { hash } from "./utils/bcrypt";

export default {
    providers: [
        Credentials({
            credentials: {
                email: { label: "Email", type: "email" },
                password: { label: "Password", type: "password" }
            },
            async authorize(credentials) {
                const validateFields = LoginSchema.safeParse(credentials);
                if (!validateFields.success) {
                    return null;
                }
                const { email, password } = validateFields.data;
                const isUser = await db.user.findUnique({
                    where: {
                        email
                    }
                })
                if (!isUser) {
                    return null;
                }
                if (hash(password) === isUser.password){
                    return isUser as any;
                }
                return null;
            }
        })
    ],
} satisfies NextAuthConfig

解决方案

1. API路由中必须传递Request对象给auth()

在Next.js API路由中,auth()需要显式接收请求对象才能读取session相关的cookie或header信息。修改route.ts中的调用:

// 原代码
const session = await auth();

// 修改后
const session = await auth(req); // 传入req参数

2. 修复Credentials提供者的密码验证逻辑

密码验证逻辑错误:数据库中存储的是哈希后的密码,不能直接将输入密码重新哈希后对比(每次哈希的盐值不同,结果不一致)。需使用bcrypt的验证方法替换:

// 原代码
if (hash(password) === isUser.password){
    return isUser as any;
}

// 修改后(假设utils/bcrypt中有verify异步方法)
import { verify } from "./utils/bcrypt";

// ...
if (await verify(password, isUser.password)){
    return isUser as any;
}

注意:bcrypt的验证方法是异步的,必须添加await。

3. 额外检查项

  • 确认.env文件中的AUTH_SECRET配置正确,且与服务器组件使用的一致;
  • 检查session策略:当前使用jwt策略,确保callbacks中的session和jwt逻辑已正确将用户ID注入session。

修改后的完整route.ts示例

import { auth } from "@/auth";
import { db } from "@/lib/db";
import { NextRequest, NextResponse } from "next/server";

export async function GET(req: NextRequest) {
    try {
        const session = await auth(req); // 传入req参数
        console.log(session, "session");
        
        if (!session) {
            return NextResponse.json({ user: null, message: 'Unauthorized' }, { status: 401 });
        }
        const id = Number(session?.user?.id);
        const user = await db.user.findUnique({
            where: { id }
        });
        if (!user) {
            return NextResponse.json({ user: null, message: 'User not found' }, { status: 404 });
        }
        const { password, ...userData } = user;
        return NextResponse.json({ user: userData, message: 'User found' }, { status: 200 });
    } catch (error: any) {
        return NextResponse.json({ error: error.message, message: "Something went wrong!" }, { status: 500 });
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 17:05:16