发布于 2024-07-09
Next Auth 最新版已集成到 Auth.js ,可以很方便地集成账号登录、第三方登录等 Web 身份验证功能。
框架网站: https://authjs.dev/
https://authjs.dev/getting-started/installation?framework=next.js
安装 beta 版本:
npm install next-auth@beta
安装教程配置:
handlers, signIn, signOut, authapp/api/auth/[...nextauth]/route.ts 文件并从 handlers 导出 { GET, POST }middleware.ts 并将 auth 重命名为 middleware 导出https://nextjs.org/docs/app/building-your-application/routing/middleware
中间件在缓存内容和路由匹配之前运行。
可配置 matcher ,利用正则排除不需要权限限制的路径:
https://authjs.dev/reference/nextjs#in-middleware
export const config = {
matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
}
https://authjs.dev/getting-started/providers/credentials
Next Auth 集成了大量的登录方式,包括最原始的账号密码凭据登录方式。
import NextAuth from "next-auth"
import Credentials from "next-auth/providers/credentials"
export const { handlers, signIn, signOut, auth } = NextAuth({
providers: [
Credentials({
credentials: {
username: { label: "Username" },
password: { label: "Password", type: "password" },
},
async authorize(credentials) {
if (credentials.username === 'admin' && credentials.password === 'admin') {
const user = {
name: credentials.username,
}
return user
}
return null
},
}),
],
})
https://authjs.dev/reference/nextjs#callbacks
callbacks: {
async authorized({ request, auth }) {
const url = request.nextUrl
const user = auth?.user;
if (url.pathname.startsWith('/admin') && !user) {
return false
}
return true
}
}
providers.Credentials.authorize 想返回一个自定义的用户格式,如:
const user = {
id: "1",
username: credentials.username,
role: 'admin'
}
拓展 next-auth 的 Session、User、JWT 类型使得 ts 可正常运行:
https://stackoverflow.com/questions/74425533
import { Session } from "next-auth";
import { JWT } from "next-auth/jwt";
declare module "next-auth" {
interface Session {
id: string;
username: string;
role: string;
}
interface User {
id: string;
username: string;
role: string;
}
}
declare module "next-auth/jwt" {
interface JWT {
id: string;
username: string;
role: string;
}
}
如需补充额外字段,可参照基于角色的访问控制教程,如将角色写进来:
https://authjs.dev/guides/role-based-access-control
callbacks: {
jwt({ token, user }) {
if (user && user.id) {
token.id = user.id
token.username = user.username
token.role = user.role
}
return token
},
session({ session, token }) {
session.user.id = token.id
session.user.username = token.username
session.user.role = token.role
return session
},
// ... authorized
}
next-auth 配置增加:
pages: {
signIn: "/login",
},
这样就会默认走到 /login 路由,在 app 目录创建路由编写页面即可。
确认登录时,调用 @/auth.ts 中导出的 signIn 方法。
调用 @/auth.ts 中导出的 signOut 方法即可。