Next.js 鉴权
Next Auth 简介
bash
pnpm add next-auth
ts
import type { NextAuthOptions } from 'next-auth'
import { userService } from '@/services/user'
import CredentialsProvider from 'next-auth/providers/credentials'
import process from 'node:process'
export const authOptions: NextAuthOptions = {
pages: {
error: '/error',
newUser: '/login',
signIn: '/login',
signOut: '/signout',
verifyRequest: '/auth/verify-request',
},
providers: [
CredentialsProvider({
async authorize(credentials, _) {
try {
return await userService.login(credentials)
}
catch (error) {
console.error(error)
return null
}
},
credentials: {
password: { label: 'Password', type: 'password' },
username: { label: 'Username', type: 'text' },
},
name: 'Credentials',
}),
],
secret: process.env.NEXTAUTH_SECRET,
}
新建 app/api/auth/[...nextauth]/route.ts
文件,内容如下:
ts
import { authOptions } from '@/lib/auth'
import NextAuth from 'next-auth'
const handler = NextAuth(authOptions)
export { handler as GET, handler as POST }
通过 signIn()
方法登录:
tsx
通过 signOut()
方法退出登录:
退出登录组件示例:
tsx
import { signOut } from 'next-auth/react'
export default function SignOutButton() {
return (
<button onClick={() => signOut()}>Sign Out</button>
)
}
退出登录会重新加载页面,可以通过传入 callbackUrl
参数来指定退出登录后跳转的页面,通过 redirect
参数来指定退出登录后是否重定向。
后端鉴权
通过 Session 可以确定用户是否登录:
ts
import { getServerSession } from 'next-auth'
export async function GET(request: NextRequest) {
const session = await getServerSession({ req: request })
if (!session) {
return new Response('Unauthorized', { status: 401 })
}
}
获取 JWT Token:
ts
import { getToken } from 'next-auth/jwt'
export async function GET(request: NextRequest) {
const token = await getToken({ req: request })
// token?.sub 为用户 ID
}