如何修改NextAuth中间件,让未授权API路由返回401而非重定向?
在NextJS中用NextAuth保护API路由并返回401而非重定向
需求:使用NextAuth保护NextJS中的API路由,未授权时返回
401响应,而非默认的重定向到/sign-in;页面路由仍保持重定向到登录页的逻辑。当前实现通过中间件判断路径是否为API,重定向到/api/unauthorized路由返回401,想知道更优方案。
更优实现方案
无需额外创建/api/unauthorized路由,直接在中间件内区分API与页面路由的未授权处理逻辑,代码更简洁高效:
import { withAuth, NextRequestWithAuth } from "next-auth/middleware"; import { NextResponse } from "next/server"; export default function middleware(req: NextRequestWithAuth) { // 判断用户是否未授权:next-auth会在授权失败时将token置为null const isUnauthorized = !req.nextauth?.token; if (isUnauthorized) { const isApiRoute = req.nextUrl.pathname.startsWith('/api'); if (isApiRoute) { // API路由直接返回401 JSON响应,符合REST规范 return NextResponse.json( { error: "未授权访问" }, { status: 401, headers: { 'WWW-Authenticate': 'Bearer' } // 符合HTTP认证头规范 } ); } else { // 页面路由重定向到登录页,附带回调URL以便登录后返回原页面 const signInUrl = new URL('/sign-in', req.url); signInUrl.searchParams.set('callbackUrl', req.nextUrl.href); return NextResponse.redirect(signInUrl); } } // 授权通过,放行请求 return NextResponse.next(); } export const config = { matcher: [ '/api/protected', '/posts/create' ] };
优化点说明
- 减少冗余路由:去掉了单独的
/api/unauthorized路由,直接在中间件完成401响应输出,避免额外的内部跳转 - 逻辑更直接:通过
req.nextauth.token直接判断授权状态,无需依赖重定向间接实现API的401返回 - 符合HTTP规范:给API响应添加
WWW-Authenticate头,明确告知客户端需要认证 - 提升用户体验:页面路由保留
callbackUrl参数,用户登录后可自动跳回之前访问的页面
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

