保护资源
保护路由通常可以通过检查会话并在未找到活动会话时采取操作来完成,例如将用户重定向到登录页面或简单地返回 401: 未经授权
响应。
页面
您可以使用从 NextAuth()
返回并在您的 auth.ts
或 auth.js
配置文件中导出的 auth
函数来获取会话对象。
app/server/page.tsx
import { auth } from "@/auth"
export default async function Page() {
const session = await auth()
if (!session) return <div>Not authenticated</div>
return (
<div>
<pre>{JSON.stringify(session, null, 2)}</pre>
</div>
)
}
API 路由
可以使用 auth
导出在各种框架中保护 API 路由。
在 Next.js 中,您可以使用 auth
函数包装 API 路由处理程序。然后请求参数将具有一个 auth
键,您可以检查它是否有有效的会话。
./app/api/admin/route.ts
import { auth } from "@/auth"
import { NextResponse } from "next/server"
export const GET = auth(function GET(req) {
if (req.auth) return NextResponse.json(req.auth)
return NextResponse.json({ message: "Not authenticated" }, { status: 401 })
})
Next.js 中间件
使用 Next.js 12+,保护一组页面的最简单方法是使用中间件文件。您可以在根页面目录中创建一个 middleware.ts
文件,其中包含以下内容。
middleware.ts
export { auth as middleware } from "@/auth"
然后在您的 auth.ts
文件中定义 authorized
回调。有关更多详细信息,请查看 参考文档。
auth.ts
import NextAuth from "next-auth"
export const { auth, handlers } = NextAuth({
callbacks: {
authorized: async ({ auth }) => {
// Logged in users are authenticated, otherwise redirect to login page
return !!auth
},
},
})
如果您想在中间件中实现更多逻辑,也可以使用 auth
方法作为包装器。
middleware.ts
import { auth } from "@/auth"
export default auth((req) => {
if (!req.auth && req.nextUrl.pathname !== "/login") {
const newUrl = new URL("/login", req.nextUrl.origin)
return Response.redirect(newUrl)
}
})
您也可以使用正则表达式匹配多个路由,或者否定某些路由以保护所有剩余路由。以下示例避免在 favicon 或静态图像等路径上运行中间件。
middleware.ts
export const config = {
matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
}
中间件将根据 matcher
配置导出定义的页面进行保护。有关匹配器的更多详细信息,请查看 Next.js 文档。
💡
您不应仅依靠中间件进行授权。始终确保尽可能接近您的数据获取来验证会话。