Nextjs+Supabase API路由认证问题:前端请求遭登录页重定向
解决前端组件调用受保护API路由被重定向的问题
核心原因
你的API路由被Supabase中间件保护,前端组件发起的请求没有附带有效的认证会话信息,导致中间件判定为未认证,触发登录页重定向。
解决方案
1. 在前端请求中携带Supabase会话令牌
当用户已登录时,前端可从Supabase客户端获取会话,在请求头中带上认证令牌:
// 前端组件内的请求代码 import { createClientComponentClient } from '@supabase/auth-helpers-nextjs'; const fetchProtectedData = async () => { const supabase = createClientComponentClient(); const { data: { session } } = await supabase.auth.getSession(); const res = await fetch('/api/protected-endpoint', { headers: { Authorization: `Bearer ${session?.access_token}`, }, }); if (!res.ok) { // 处理会话过期等错误场景 throw new Error('请求失败'); } const data = await res.json(); return data; };
2. 调整API路由的认证校验逻辑
让API路由主动校验令牌并返回HTTP状态码(而非重定向),适配前端请求的处理逻辑:
// /api/protected-endpoint/route.js import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs'; import { cookies } from 'next/headers'; export async function GET(request) { const supabase = createRouteHandlerClient({ cookies }); const { data: { session } } = await supabase.auth.getSession(); if (!session) { // 返回401状态码,交由前端处理未授权场景 return new Response('未授权', { status: 401 }); } // 执行业务逻辑并返回数据 return new Response(JSON.stringify({ data: '受保护内容' }), { headers: { 'Content-Type': 'application/json' }, }); }
3. 优化中间件规则(可选)
若中间件是全局拦截所有请求,可调整匹配规则,让API路由请求跳过重定向逻辑,由API自身校验:
// middleware.js import { createMiddlewareClient } from '@supabase/auth-helpers-nextjs'; import { NextResponse } from 'next/server'; export async function middleware(req) { const res = NextResponse.next(); const supabase = createMiddlewareClient({ req, res }); const { data: { session } } = await supabase.auth.getSession(); // API路由请求直接放行,由路由自身处理认证 if (req.nextUrl.pathname.startsWith('/api/')) { return res; } // 仅对页面请求做重定向处理 if (!session && req.nextUrl.pathname !== '/login') { return NextResponse.redirect(new URL('/login', req.url)); } return res; } export const config = { matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'], };
关键注意点
- 前端请求必须在用户已登录的上下文发起,确保能获取有效session
- API返回401后,前端可监听状态码,触发会话刷新或跳转登录页
- 保持API路由的保护机制,不要设为公开
内容的提问来源于stack exchange,提问作者Preet Patel
相关产品推荐
相关产品推荐

