什么是 next-auth
next-auth 是一個(gè)專門為 Next.js 設(shè)計(jì)的启泣、易于使用的奋姿、靈活的身份驗(yàn)證庫(kù)。它簡(jiǎn)化了為你的應(yīng)用程序添加身份驗(yàn)證(如登錄、注冊(cè)聂宾、登出等)的過程遥诉。next-auth 支持多種認(rèn)證方式,包括通過電子郵件和密碼、OAuth 2.0 提供商(如 Google吨枉、GitHub、Facebook 等)哄芜、以及自定義提供商貌亭。
以下是它的一些主要特點(diǎn):
-
內(nèi)置 OAuth 提供商
:next-auth 內(nèi)置支持多個(gè) OAuth 和 OpenID Connect 提供商,使得與第三方服務(wù)集成變得簡(jiǎn)單认臊。 -
會(huì)話管理
:提供了簡(jiǎn)單的 API 來處理用戶會(huì)話圃庭,允許開發(fā)者輕松地獲取當(dāng)前用戶的會(huì)話信息。 -
數(shù)據(jù)庫(kù)兼容性
:可以與多種數(shù)據(jù)庫(kù)一起使用失晴,以存儲(chǔ)用戶數(shù)據(jù)剧腻。它支持無頭 CMS 和自定義后端。 -
多語言支持
:內(nèi)置對(duì)多語言的支持涂屁,可以根據(jù)用戶的偏好語言顯示錯(cuò)誤消息和其他文本书在。 -
自定義頁(yè)面
:允許創(chuàng)建自定義的登錄、注冊(cè)或錯(cuò)誤頁(yè)面拆又,以便更好地融入應(yīng)用程序的設(shè)計(jì)風(fēng)格儒旬。 -
安全默認(rèn)值
:采用了安全的默認(rèn)設(shè)置栏账,幫助保護(hù)應(yīng)用免受常見的安全問題影響。 -
API 路由
:利用 Next.js 的 API 路由功能來處理身份驗(yàn)證邏輯栈源,這意味著你可以創(chuàng)建自己的端點(diǎn)來進(jìn)行登錄挡爵、登出等操作。 -
JWT 或數(shù)據(jù)庫(kù)會(huì)話
:可以選擇使用 JSON Web Tokens (JWT) 進(jìn)行狀態(tài)無會(huì)話管理甚垦,或者選擇基于數(shù)據(jù)庫(kù)的會(huì)話茶鹃。 -
適配器支持
:對(duì)于想要將用戶數(shù)據(jù)持久化到數(shù)據(jù)庫(kù)中的情況,next-auth 提供了適配器(adapters)艰亮,可以方便地與不同的數(shù)據(jù)庫(kù)系統(tǒng)進(jìn)行集成前计,比如 Prisma、TypeORM 等垃杖。
具體步驟
- 安裝依賴
pnpm add next-auth@beta
- 設(shè)置環(huán)境
唯一強(qiáng)制的環(huán)境變量是AUTH_SECRET
男杈,這是庫(kù)用來加密令牌和電子郵件驗(yàn)證散列的隨機(jī)值。運(yùn)行以下命令隨機(jī)生成一個(gè):
npx auth secret
這也會(huì)將其添加到本地的 .env
文件中
- 配置
在應(yīng)用的根目錄下創(chuàng)建一個(gè)新的auth.ts
文件调俘,包含以下內(nèi)容:
import NextAuth from "next-auth"
export const { handlers, signIn, signOut, auth } = NextAuth({
providers: [],
})
- 在
/app/api/auth/[...nextauth]/route.ts
下添加路由處理程序:
import { handlers } from "@/auth" // Referring to the auth.ts we just created
export const { GET, POST } = handlers
配置 Github Provider
-
打開 OAuth Apps 頁(yè)面伶棒,點(diǎn)擊
New Oauth App
07w44g5g1akl2q3j3j35po0lax75voom.png -
填入項(xiàng)目的信息,這里的
Homepage URL
我們可以先填本地開發(fā)的地址彩库,等部署上線再改成線上地址肤无,Authorization callback URL
填入https://example.com/api/auth/callback/github
,然后點(diǎn)擊Register Application
n6jdiavhfkx03jebcp6uvkrrp9sl36jb.png -
打開剛創(chuàng)建的
Oauth App
骇钦,這里可以根據(jù)需要設(shè)置Oauth App
信息宛渐,點(diǎn)擊Generate a new client secret
復(fù)制密鑰
xrxwpqoy8nes7ihciwq7pggalmmsaewr.png 在根目錄的
.env
文件中填入剛才復(fù)制的密鑰
GITHUB_ID= 'xxxxx'
GITHUB_SECRET= 'xxxxxxxxx'
- 打開
/src/auth.ts
文件,配置Github Provider
信息
import NextAuth from "next-auth"
import GitHub from "next-auth/providers/github"
export const { handlers, auth, signIn, signOut } = NextAuth({
providers: [
GitHub({
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
})
],
})
會(huì)話管理
- 服務(wù)器組件 - 登錄
import { signIn } from "@/auth.ts"
export function SignIn() {
return (
<form
action={async () => {
"use server"
await signIn("github", { redirectTo: "/dashboard" })
}}
>
<button type="submit">Sign in</button>
</form>
)
}
- 服務(wù)器組件 - 退出
import { signOut } from "@/auth.ts"
export function SignOut() {
return (
<form
action={async () => {
"use server"
await signOut()
}}
>
<button type="submit">Sign Out</button>
</form>
)
}
- 客戶端組件 - 登錄
"use client"
import { signIn } from "next-auth/react"
export function SignIn() {
return (
<button onClick={() => signIn("github", { redirectTo: "/dashboard" })}>
Sign In
</button>
)
}
- 客戶端組件 - 退出
"use client"
import { signOut } from "next-auth/react"
export function SignOut() {
return <button onClick={() => signOut()}>Sign Out</button>
}
-
新建一個(gè)登錄界面眯搭,點(diǎn)擊登錄按鈕窥翩,就能看到跳轉(zhuǎn)到
Github
授權(quán)信息
3ex00k87v4wful85eyjs0f43lmmduj1a.png -
打開控制臺(tái),就能看到
session
會(huì)話信息鳞仙,如果沒有登錄則返回null
km9t2er59vqhn2zy3vsfbvtfc8zebn3i.png
適配器 Adapters
在 next-auth 中寇蚊,適配器(adapters)的主要作用是為會(huì)話管理和用戶數(shù)據(jù)持久化提供數(shù)據(jù)庫(kù)支持。適配器使得 next-auth 可以與不同的數(shù)據(jù)庫(kù)系統(tǒng)進(jìn)行交互棍好,以便存儲(chǔ)和檢索用戶信息仗岸、會(huì)話數(shù)據(jù)以及其他相關(guān)的認(rèn)證信息,下面以 Prisma 為例
- 安裝軟件包
pnpm add @prisma/client @auth/prisma-adapter
pnpm add prisma --save-dev
- 設(shè)置環(huán)境變量
DATABASE_URL=postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=SCHEMA
- 配置實(shí)例
import { PrismaClient } from "@prisma/client"
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient }
export const prisma = globalForPrisma.prisma || new PrismaClient()
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma
- 打開
/src/auth.ts
文件借笙,配置實(shí)例信息
import NextAuth from "next-auth"
import { PrismaAdapter } from "@auth/prisma-adapter"
import { prisma } from "@/prisma"
export const { handlers, auth, signIn, signOut } = NextAuth({
adapter: PrismaAdapter(prisma),
providers: [],
})
- 在根目錄
prisma/schema.prisma
創(chuàng)建模型文件
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id String @id @default(cuid())
name String?
email String @unique
emailVerified DateTime?
image String?
accounts Account[]
sessions Session[]
// Optional for WebAuthn support
Authenticator Authenticator[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Account {
userId String
type String
provider String
providerAccountId String
refresh_token String?
access_token String?
expires_at Int?
token_type String?
scope String?
id_token String?
session_state String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@id([provider, providerAccountId])
}
model Session {
sessionToken String @unique
userId String
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model VerificationToken {
identifier String
token String
expires DateTime
@@id([identifier, token])
}
// Optional for WebAuthn support
model Authenticator {
credentialID String @unique
userId String
providerAccountId String
credentialPublicKey String
counter Int
credentialDeviceType String
credentialBackedUp Boolean
transports String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@id([userId, credentialID])
}
以上是 PostgreSQL 數(shù)據(jù)庫(kù)的模型扒怖,如果是其他數(shù)據(jù)庫(kù),請(qǐng)參考:Prisma Adapter
-
在用戶登錄后业稼,用戶的會(huì)話信息就會(huì)自動(dòng)保存到數(shù)據(jù)庫(kù):
zvqzb608197tpi0oi0xjn2mqbhx5uxbf.png
總結(jié)
- 本文只演示了
Github
平臺(tái)的身份鑒權(quán)盗痒,其他平臺(tái)應(yīng)該也大差不差 - next-auth 還有很多強(qiáng)大的功能需要我們?nèi)ヌ剿?/li>
Github
:next-admin
線上預(yù)覽地址
:Next Admin