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

如何在Next.js项目中对接已有Node+Express后端使用NextAuth?

自定义Node后端返回Token时的NextAuth身份验证实现

原场景:Next项目内直连数据库的NextAuth配置

以下是api/auth/[...nextauth]/route.ts中直连数据库的典型配置:

import { connectDB } from "@/libs/mongodb";
import User from "@/models/user";
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import bcrypt from "bcryptjs";

const handler = NextAuth({
  providers: [
    CredentialsProvider({
      name: "Credentials",
      id: "credentials",
      credentials: {
        email: { label: "Email", type: "text", placeholder: "jsmith" },
        password: { label: "Password", type: "password" },
      },
      async authorize(credentials) {
        await connectDB();
        const userFound = await User.findOne({
          email: credentials?.email,
        }).select("+password");

        if (!userFound) throw new Error("Invalid credentials");

        const passwordMatch = await bcrypt.compare(
          credentials!.password,
          userFound.password
        );

        if (!passwordMatch) throw new Error("Invalid credentials");

        console.log(userFound);

        return userFound;
      },
    }),
  ],
  pages: {
    signIn: "/login",
  },
  session: {
    strategy: "jwt",
  },
  callbacks: {
    async jwt({ token, user }) {
      if (user) token.user = user;
      return token;
    },
    async session({ session, token }) {
      session.user = token.user as any;
      return session;
    },
  },
});

export { handler as GET, handler as POST };

对接返回Token的自定义Node后端实现方案

如果你的自定义Node后端在登录/认证流程中返回JWT Token,可按以下步骤修改NextAuth配置:

1. 调整CredentialsProvider的验证逻辑

不再直连数据库,改为调用后端登录接口验证用户凭证,获取Token和用户信息:

import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";

const handler = NextAuth({
  providers: [
    CredentialsProvider({
      name: "Credentials",
      credentials: {
        email: { label: "Email", type: "text" },
        password: { label: "Password", type: "password" },
      },
      async authorize(credentials) {
        // 调用自定义Node后端的登录接口
        const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/auth/login`, {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify({
            email: credentials?.email,
            password: credentials?.password,
          }),
        });

        const data = await response.json();

        // 验证接口返回状态,失败则抛出错误
        if (!response.ok || !data.token) {
          throw new Error(data.message || "登录失败");
        }

        // 返回用户信息和后端返回的Token
        return {
          id: data.user.id,
          name: data.user.name,
          email: data.user.email,
          token: data.token,
        };
      },
    }),
  ],
  pages: {
    signIn: "/login",
  },
  session: {
    strategy: "jwt", // 保持JWT策略,存储自定义Token
  },
  callbacks: {
    // 在JWT中存储后端返回的Token和用户信息
    async jwt({ token, user }) {
      if (user) {
        token.user = {
          id: user.id,
          name: user.name,
          email: user.email,
        };
        token.accessToken = user.token; // 存储后端的JWT Token
      }
      return token;
    },
    // 将Token和用户信息注入到session中,供前端使用
    async session({ session, token }) {
      session.user = token.user as any;
      session.accessToken = token.accessToken as string;
      return session;
    },
  },
  // 配置JWT加密密钥,需与.env中的NEXTAUTH_SECRET保持一致
  secret: process.env.NEXTAUTH_SECRET,
});

export { handler as GET, handler as POST };

2. 前端使用验证逻辑

在前端组件中,通过useSession钩子获取accessToken,调用后端接口时携带该Token:

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

const ProfilePage = () => {
  const { data: session } = useSession();

  const fetchUserProfile = async () => {
    const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/user/profile`, {
      headers: {
        Authorization: `Bearer ${session?.accessToken}`,
      },
    });
    const profile = await response.json();
    // 处理用户信息
  };

  return <div>用户页面</div>;
};

export default ProfilePage;

3. 自定义Node后端的Token验证示例

后端需要验证前端传来的Token,确保请求合法性:

const jwt = require("jsonwebtoken");

const authenticateToken = (req, res, next) => {
  const authHeader = req.headers["authorization"];
  const token = authHeader && authHeader.split(" ")[1];

  if (!token) {
    return res.status(401).json({ message: "未提供Token" });
  }

  jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
    if (err) {
      return res.status(403).json({ message: "无效的Token" });
    }
    req.user = user;
    next();
  });
};

// 受保护的路由示例
app.get("/user/profile", authenticateToken, (req, res) => {
  res.json({ user: req.user });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 00:47:08