Next.js中间件仅本地生效,如何使其在Vercel部署环境正常工作?
Next.js 部署到Vercel后NextAuth中间件异常问题
我正在学习Next.js,编写了一个简单的middleware.ts:
export { default } from 'next-auth/middleware'; export const config = { matcher: ['/items', '/dashboard'] };
该中间件在本地开发环境可正常工作:未登录时无法访问/items和/dashboard。但部署到Vercel后出现异常:
- 未登录时,可正常跳转至登录页面(符合预期);
- 已登录状态下访问
/items或/dashboard,会被重定向至无需登录的首页/。
以下是我的[...nextauth]/route.ts代码:
import NextAuth from 'next-auth'; import CredentialsProvider from 'next-auth/providers/credentials'; import { compare } from 'bcrypt'; import { sql } from '@vercel/postgres'; const handler = NextAuth({ session: { strategy: 'jwt', }, pages: { signIn: '/login', }, providers: [ CredentialsProvider({ credentials: { email: {}, password: {}, }, async authorize(credentials, req) { const response = await sql` SELECT * FROM users WHERE email=${credentials?.email}`; const user = response.rows[0]; const passwordCorrect = await compare( credentials?.password || '', user.password ); console.log({ passwordCorrect }); if (passwordCorrect) { return { id: user.id, email: user.email, }; } return null; }, }), ], }); export { handler as GET, handler as POST };
文件结构如下:
├── app ├── api └── auth └── [...nextauth] └── route.ts ├── items └── page.tsx ├── dashboard └── page.tsx ├── public ├── .env ├── middleware.ts ├── next.config.mjs ├── README.md
补充:再次访问应用时,浏览器控制台出现错误,同时附上登录页面相关代码:
app/login/form.tsx:
"use client"; import { signIn } from "next-auth/react"; import { useRouter } from "next/navigation"; import { FormEvent } from "react"; export default function Form() { const router = useRouter(); const handleSubmit = async (e: FormEvent<HTMLFormElement>) => { e.preventDefault(); const formData = new FormData(e.currentTarget); const response = await signIn("credentials", { email: formData.get("email"), password: formData.get("password"), redirect: false, }); console.log({ response }); if (!response?.error) { router.push("/items"); router.refresh(); } }; return ( <form onSubmit={handleSubmit}> {/* E-mail */} <div className="mb-4"> <label htmlFor="email" className="block text-gray-700 text-sm font-bold mb-2" > E-mail </label> <input type="email" id="email" name="email" className="w-full p-2 border border-gray-300 rounded" placeholder="Seu e-mail" required /> </div> {/* Senha */} <div className="mb-6"> <label htmlFor="password" className="block text-gray-700 text-sm font-bold mb-2" > Senha </label> <input type="password" id="password" name="password" className="w-full p-2 border border-gray-300 rounded" placeholder="Sua senha" required /> </div> {/* Botão de Entrar */} <button type="submit" className="w-full bg-blue-500 text-white p-2 rounded hover:bg-blue-600 transition duration-300" > Login </button> </form> ); }
app/login/page.tsx:
import { getServerSession } from "next-auth"; import Form from "./form"; import { redirect } from "next/navigation"; export default async function LoginPage() { const session = await getServerSession(); if (session) { redirect("/"); } return ( <main className="flex flex-col items-center justify-center bg-gray-100 h-full w-full"> <div className="flex items-center justify-center "> <div className="bg-white p-8 rounded shadow-md w-96"> <h1 className="text-2xl font-bold mb-4">Login</h1> {/* Formulário */} <Form /> </div> </div> </main> ); }
内容的提问来源于stack exchange,提问作者dankwx
相关产品推荐
相关产品推荐

