Next.js+Supabase登录功能405错误及状态反馈实现问题
问题描述
我按照官方文档实现了基于Next.js的登录页面(路径:/app/login/page.tsx)和Supabase认证路由(路径:/app/auth/login/route.ts),但无法添加登录成功提示与错误处理逻辑。参考方案修改代码后,出现错误:POST http://localhost:3000/auth/login net::ERR_ABORTED 405 (Method Not Allowed),以下是修改前后的相关代码,求解决办法。
初始代码
路由文件 /app/auth/login/route.ts
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs' import { cookies } from 'next/headers' import { NextResponse } from 'next/server' export async function POST(request: Request) { const requestUrl = new URL(request.url) const formData = await request.formData() const email = String(formData.get('email')) const password = String(formData.get('password')) const cookieStore = cookies() const supabase = createRouteHandlerClient({ cookies: () => cookieStore }) await supabase.auth.signInWithPassword({ email, password, }) return NextResponse.redirect(requestUrl.origin, { status: 301, }) }
登录页面 /app/login/page.tsx
import Link from "next/link"; export default function LoginPage() { return ( <> <form action="/auth/login" method="post"> <label htmlFor="email">Email</label> <input name="email" /> <label htmlFor="password">Password</label> <input type="password" name="password" /> <button>Sign In</button> </form> <Link href="/reset-password">Reset Password</Link> </> ) }
修改后代码
路由文件 /app/auth/login/route.ts
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs'; import { NextApiRequest, NextApiResponse } from 'next'; import { cookies } from 'next/headers'; import { NextResponse } from 'next/server'; export async function handler( req: NextApiRequest, res: NextApiResponse ) { const jsonBody = await req.body.json(); const email = jsonBody.email; const password = jsonBody.password; const cookieStore = cookies(); const supabase = createRouteHandlerClient({ cookies: () => cookieStore }); try { const { error } = await supabase.auth.signInWithPassword({ email, password, }); if (error) { return res.status(401).json({ message: 'Login failed. Please check your credentials.' }); } return res.status(200).json({ message: 'Login successful' }); } catch (error) { console.error('An error occurred:', error); return res.status(500).json({ message: 'An unexpected error occurred' }); } }
登录页面 /api/login/page.tsx
'use client' import { useRouter } from 'next/navigation'; import { useState } from 'react'; export default function LoginPage() { const router = useRouter(); const [error, setError] = useState<string>(''); const [email, setEmail] = useState<string>(''); const [password, setPassword] = useState<string>(''); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(''); try { const response = await fetch('/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ email, password }), }); if (response.status === 200) { router.push('/'); } else { if (response.headers.get('content-type')?.includes('application/json')) { const result = await response.json(); setError(result.message); } else { setError('An unexpected error occurred.'); } } } catch (error) { console.log(error, "error on the login page.tsx") console.error('An error occurred:', error); setError('An unexpected error occurred.'); } }; return ( <> <form onSubmit={handleSubmit}> <label htmlFor="email">Email</label> <input type="email" name="email" value={email} onChange={(e) => setEmail(e.target.value)} /> <label htmlFor="password">Password</label> <input type="password" name="password" value={password} onChange={(e) => setPassword(e.target.value)} /> <button type="submit">Sign In</button> </form> {error && <p>{error}</p>} </> ); }
解决办法
1. 修复认证路由文件(/app/auth/login/route.ts)
修改后的路由误用了Pages Router的handler写法,而你的项目是App Router结构,必须导出POST方法而非handler,同时使用App Router的Request对象处理请求:
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs'; import { cookies } from 'next/headers'; import { NextResponse } from 'next/server'; export async function POST(request: Request) { const cookieStore = cookies(); const supabase = createRouteHandlerClient({ cookies: () => cookieStore }); try { const { email, password } = await request.json(); const { error } = await supabase.auth.signInWithPassword({ email, password }); if (error) { return NextResponse.json( { message: '登录失败,请检查账号密码' }, { status: 401 } ); } return NextResponse.json({ message: '登录成功' }, { status: 200 }); } catch (err) { console.error('登录出错:', err); return NextResponse.json( { message: '服务器发生意外错误' }, { status: 500 } ); } }
2. 修正登录页面路径
将修改后的页面路径从/api/login/page.tsx改回原路径/app/login/page.tsx,确保前端请求的路由与后端路由匹配。
3. 关键错误原因
- App Router的路由文件必须导出
GET/POST等HTTP方法,不能使用Pages Router的handler函数,这是导致405(方法不允许)错误的核心原因。 NextApiRequest/NextApiResponse是Pages Router的专属类型,App Router中应使用Web标准的Request对象和NextResponse处理响应。
内容的提问来源于stack exchange,提问作者JS3
相关产品推荐
相关产品推荐

