我在 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'
}
到目前为止我检查过的内容:
问题:
不要忘记在 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
//...