NextAuth 中间件无法在生产中检索令牌

问题描述 投票:0回答:1

我在 Next.js 应用程序中使用 NextAuth 和自定义凭据提供程序。在我的本地开发环境中一切正常,但在生产中(部署在 Vercel 上),中间件无法检索令牌,导致用户卡在登录页面。

这是我的nextauth配置文件:

 import connectMongoDB from "@/libs/mongodb";
    import NextAuth from "next-auth";
    import CredentialsProvider from "next-auth/providers/credentials";
    import User from "@/models/User";
    import bcryptjs from "bcryptjs";
    
    export const authOptions = {
      providers: [
        CredentialsProvider({
          name: "credentials",
          credentials: {
            siteID: { label: "Site ID", type: "text" },
            email: { label: "Email", type: "text" },
            password: { label: "Password", type: "password" },
          },
          async authorize(credentials) {
            const { siteID, email, password } = credentials;
            try {
              await connectMongoDB();
              const user = await User.findOne({ siteID, email });
              if (!user) {
                console.error("No user found with the provided credentials");
                return null;
              }
              const validPassword = await bcryptjs.compare(password, user.password);
              if (!validPassword) {
                console.error("Invalid password");
                return null;
              }
              return user;
            } catch (error) {
              console.error("Error in authorization:", error);
              return null;
            }
          },
        }),
      ],
      callbacks: {
        async jwt({ token, user, session, trigger }) {
          if (trigger === "update" && session?.name) {
            token.name = session.name;
          }
          if (user) {
            return {
              ...token,
              id: user._id,
              name: user.name,
              siteID: user.siteID,
            };
          }
          return token;
        },
        async session({ session, token }) {
          return {
            ...session,
            user: {
              ...session.user,
              id: token.id,
              name: token.name,
              siteID: token.siteID,
            },
          };
        },
      },
      secret: process.env.NEXTAUTH_SECRET || "consultancyproject",
      session: {
        strategy: "jwt",
        maxAge: 15 * 60,
        updateAge: 10 * 60,
      },
      pages: {
        signIn: "/Login",
      },
      events: {
        async signOut(message) {
          console.log("User signed out", message);
        },
        async sessionExpired(message) {
          console.log("Session expired", message);
        },
      },
    };
    
    const handler = NextAuth(authOptions);
    
    export { handler as GET, handler as POST };

这是我的中间件文件:

import { NextResponse } from "next/server";
import { getToken } from "next-auth/jwt";

export async function middleware(request) {
  console.log("Middleware called. Request URL:", request.url);
  console.log("NEXTAUTH_SECRET:", process.env.NEXTAUTH_SECRET);
  
  let token;
  try {
    token = await getToken({
      req: request,
      secret: process.env.NEXTAUTH_SECRET,
    });
    console.log("Token retrieved:", token);
  } catch (error) {
    console.error("Error retrieving token:", error);
    return NextResponse.redirect(new URL("/Login", request.url));
  }

  const path = request.nextUrl.pathname;
  console.log("Requested path:", path);

  const publicPaths = [
    "/",
    "/Signup",
    "/Login",
    "/ForgotPassword",
    "/ResetPassword",
    "/ChoosePlan",
  ];

  const isPublicPath = publicPaths.includes(path);
  console.log("Is public path:", isPublicPath);

  // Redirect authenticated users away from public paths to the dashboard
  if (isPublicPath && token) {
    console.log("Authenticated user trying to access public path. Redirecting to /Dashboard");
    return NextResponse.redirect(new URL("/Dashboard", request.url));
  }

  // Redirect unauthenticated users trying to access protected paths to the login page
  if (!isPublicPath && !token) {
    console.log("Unauthenticated user trying to access protected path. Redirecting to /Login");
    return NextResponse.redirect(new URL("/Login", request.url));
  }

  // Continue with the request if the user is authenticated or accessing a public path
  console.log("User is authenticated or accessing public path. Continuing with request.");
  return NextResponse.next();
}

export const config = {
  matcher: [
    "/",  
    "/Admin",
    "/Cases",
    "/Dashboard",
    "/ForgotPassword",
    "/Home",
    "/NotAuthorized",
    "/PaymentSuccess",
    "/Reports",
    "/Signup",
    "/ChoosePlan",
    "/Emails",
    "/Form",
    "/ResetPassword",
    

], };

在生产中,日志表明未检索令牌:

***User is authenticated or accessing public path. Continuing with request.
GET /Login
Is public path: true
GET /Login
Requested path: /Login
Token retrieved: null***

这些是来自 nextauth 文件的日志:

Session callback token: {
  email: '[email protected]',
  sub: '668e24f188a5984c9650b971',
  id: '668e24f188a5984c9650b971',
  siteID: 'GC7U35TAFX',
  iat: 1721071538,
  exp: 1723663538,
  jti: '63301835-155f-4ef0-8eb9-7cff5f93d203'
}
JWT callback token: {
  email: '[email protected]',
  sub: '668e24f188a5984c9650b971',
  id: '668e24f188a5984c9650b971',
  siteID: 'GC7U35TAFX',
  iat: 1721071538,
  exp: 1723663538,
  jti: '63301835-155f-4ef0-8eb9-7cff5f93d203'
}

到目前为止我检查过的内容:

  1. 验证 NEXTAUTH_SECRET 在 Vercel 中正确设置 环境变量。
  2. 确保在生产中启用安全 cookie。
  3. 添加了详细的日志记录以跟踪令牌检索过程。

问题:

  1. 为什么令牌检索在生产中工作时失败 完美的开发环境?
  2. 如何进一步调试并修复此问题以确保令牌检索 在生产中工作吗?任何见解或建议都会非常有用 赞赏!
token vercel next-auth nextjs14
1个回答
0
投票

不要忘记在 Dockerfile 中添加环境变量(如果使用的话)

E.x.

//...

ENV API_BASE_URL=https://api.example.com
ENV API_KEY=i175e99e-99x1-5e18-52bb-1u98c30ef83c
ENV AUTH_SECRET=an2af0596604344x3g015a789ba447uj
ENV AUTH_URL=https://www.example.com/api/auth

//...
© www.soinside.com 2019 - 2024. All rights reserved.