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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 16:35:03