轉接器
Auth.js 可以與任何資料層(資料庫、ORM 或後端 API、HTTP 客戶端)整合,以便自動建立使用者、自動處理帳戶連結、支援無密碼登入,並儲存工作階段資訊。
此模組包含建立 Auth.js 相容轉接器的實用函數和類型。
Auth.js 支援 2 種工作階段策略來保存使用者的登入狀態。預設是使用 Cookie + 基於 JWT 的工作階段儲存 (strategy: "jwt"
),您也可以使用資料庫轉接器將工作階段儲存在資料庫中。
在繼續之前,Auth.js 有一個官方資料庫轉接器的清單。如果您的資料庫列在那裡,您可能不需要建立自己的轉接器。如果您使用的資料解決方案無法與官方轉接器整合,此模組將協助您建立相容的轉接器。
注意 雖然 @auth/core
*是*框架/執行階段不可知論的,但轉接器可能會依賴於客戶端/ORM 套件,該套件尚未與您的框架/執行階段相容(例如,它可能依賴於 Node.js API)。相關問題應報告給相應的套件維護人員。
安裝
npm install @auth/core
然後,您可以從 @auth/core/adapters
匯入此子模組。
用法
每個轉接器方法及其函數簽名都記錄在轉接器介面中。
import { type Adapter } from "@auth/core/adapters"
// 1. Simplest form, a plain object.
export const MyAdapter: Adapter {
// implement the adapter methods here
}
// or
// 2. A function that returns an object. Official adapters use this pattern.
export function MyAdapter(config: any): Adapter {
// Instantiate a client/ORM here with the provided config, or pass it in as a parameter.
// Usually, you might already have a client instance elsewhere in your application,
// so you should only create a new instance if you need to or you don't have one.
return {
// implement the adapter methods
}
}
然後,您可以將您的轉接器作為 adapter
選項傳遞給 Auth.js。
import { MyAdapter } from "./my-adapter"
const response = await Auth(..., {
adapter: MyAdapter, // 1.
// or
adapter: MyAdapter({ /* config */ }), // 2.
...
})
請注意,您或許可以調整現有的轉接器,使其與您的資料層一起使用,而不是從頭開始建立一個。
import { type Adapter } from "@auth/core/adapters"
import { PrismaAdapter } from "@auth/prisma-adapter"
import { PrismaClient } from "@prisma/client"
const prisma = new PrismaClient()
const adapter: Adapter = {
...PrismaAdapter(prisma),
// Add your custom methods here
}
const request = new Request("https://example.com")
const response = await Auth(request, { adapter, ... })
模型
Auth.js 可以與任何資料庫一起使用。模型會告訴您 Auth.js 期望從資料庫中獲得哪些結構。模型會根據您使用的轉接器而略有不同,但通常會具有與下圖相似的結構。每個模型都可以使用其他欄位擴充。
Auth.js / NextAuth.js 對於其資料庫列使用 camelCase
,同時尊重 OAuth 相關值的傳統 snake_case
格式。如果混合大小寫對您來說是個問題,大多數轉接器都有專門的說明文件章節,說明如何強制執行大小寫慣例。
測試
有一個可用的測試套件,以確保您的轉接器與 Auth.js 相容。
已知問題
以下是 Auth.js 中缺少內建功能,但可以在使用者端解決的問題。如果您想協助實作這些功能,請聯絡我們。
令牌輪換
Auth.js *目前*不支援開箱即用的access_token
輪換。必要的資訊(refresh_token
、到期時間等)會儲存在資料庫中,但輪換令牌的邏輯尚未在核心程式庫中實作。本指南應提供在使用者端執行此操作的必要步驟。
聯合登出
Auth.js *目前*不支援開箱即用的聯合登出。這表示即使從資料庫中刪除了活動的工作階段,使用者仍會登入身分識別提供者,他們只會從應用程式登出。例如,如果您使用 Google 作為身分識別提供者,並且從資料庫中刪除了工作階段,則使用者仍會登入 Google,但他們會從您的應用程式登出。
如果您的使用者可能會從公開共用的電腦(例如:圖書館)使用應用程式,您可能會想要實作聯合登出。
轉接器
轉接器是一個物件,具有從資料來源讀取和寫入資料的函數屬性(方法)。將這些方法視為將資料層正規化為 Auth.js 可以理解的通用介面的方法。
這使得 Auth.js 非常靈活,並允許它與任何資料層一起使用。
轉接器方法用於執行下列操作
- 建立/更新/刪除使用者
- 連結/取消連結使用者的一個或多個帳戶
- 處理活動的工作階段
- 支援跨多個裝置的無密碼驗證
如果未實作任何方法,但 Auth.js 呼叫了這些方法,則會向使用者顯示錯誤,且操作將會失敗。
方法
createAuthenticator()?
optional createAuthenticator(authenticator): Awaitable<AdapterAuthenticator>
建立新的驗證器。
如果建立失敗,轉接器必須拋出錯誤。
參數
參數 | 類型 |
---|---|
authenticator | AdapterAuthenticator |
回傳
Awaitable
<AdapterAuthenticator
>
createSession()?
optional createSession(session): Awaitable<AdapterSession>
為使用者建立一個會話並回傳它。
另請參閱 資料庫會話管理
參數
參數 | 類型 |
---|---|
session | 物件 |
session.expires | Date |
session.sessionToken | string |
session.userId | string |
回傳
createUser()?
optional createUser(user): Awaitable<AdapterUser>
在資料庫中建立使用者並回傳它。
另請參閱 使用者管理
參數
參數 | 類型 |
---|---|
user | AdapterUser |
回傳
createVerificationToken()?
optional createVerificationToken(verificationToken): Awaitable<undefined | null | VerificationToken>
建立驗證令牌並回傳它。
另請參閱 驗證令牌
參數
參數 | 類型 |
---|---|
verificationToken | VerificationToken |
回傳
Awaitable
<undefined
| null
| VerificationToken
>
deleteSession()?
optional deleteSession(sessionToken): Promise<void> | Awaitable<undefined | null | AdapterSession>
從資料庫中刪除一個會話。為了記錄目的,建議此方法也回傳正在刪除的會話。
另請參閱 資料庫會話管理
參數
參數 | 類型 |
---|---|
sessionToken | string |
回傳
Promise
<void
> | Awaitable
<undefined
| null
| AdapterSession
>
deleteUser()?
optional deleteUser(userId): Promise<void> | Awaitable<undefined | null | AdapterUser>
參數
參數 | 類型 |
---|---|
userId | string |
回傳
Promise
<void
> | Awaitable
<undefined
| null
| AdapterUser
>
待辦事項
目前尚未調用此方法。
另請參閱 使用者管理
getAccount()?
optional getAccount(providerAccountId, provider): Awaitable<null | AdapterAccount>
依據供應商帳戶 ID 和供應商取得帳戶。
如果找不到帳戶,轉接器必須回傳 null
。
參數
參數 | 類型 |
---|---|
providerAccountId | string |
provider | string |
回傳
Awaitable
<null
| AdapterAccount
>
getAuthenticator()?
optional getAuthenticator(credentialID): Awaitable<null | AdapterAuthenticator>
從驗證器的 credentialID 回傳驗證器。
如果找不到驗證器,轉接器必須回傳 null
。
參數
參數 | 類型 |
---|---|
credentialID | string |
回傳
Awaitable
<null
| AdapterAuthenticator
>
getSessionAndUser()?
optional getSessionAndUser(sessionToken): Awaitable<null | {
session: AdapterSession;
user: AdapterUser;
}>
一次從資料庫回傳一個會話和一個使用者。
如果資料庫支援聯結,建議減少資料庫查詢的次數。
另請參閱 資料庫會話管理
參數
參數 | 類型 |
---|---|
sessionToken | string |
回傳
Awaitable
<null
| { session
: AdapterSession
; user
: AdapterUser
; }>
getUser()?
optional getUser(id): Awaitable<null | AdapterUser>
透過使用者 ID 從資料庫回傳使用者。
另請參閱 使用者管理
參數
參數 | 類型 |
---|---|
id | string |
回傳
Awaitable
<null
| AdapterUser
>
getUserByAccount()?
optional getUserByAccount(providerAccountId): Awaitable<null | AdapterUser>
使用特定帳戶的供應商 ID 和使用者 ID,取得使用者。
另請參閱 使用者管理
參數
參數 | 類型 |
---|---|
providerAccountId | Pick <AdapterAccount , "provider" | "providerAccountId" > |
回傳
Awaitable
<null
| AdapterUser
>
getUserByEmail()?
optional getUserByEmail(email): Awaitable<null | AdapterUser>
透過使用者的電子郵件地址從資料庫回傳使用者。
另請參閱 驗證令牌
參數
參數 | 類型 |
---|---|
email | string |
回傳
Awaitable
<null
| AdapterUser
>
linkAccount()?
optional linkAccount(account): Promise<void> | Awaitable<undefined | null | AdapterAccount>
此方法在內部調用 (但也可以選擇用於手動連結)。它會在資料庫中建立一個 帳戶。
另請參閱 使用者管理
參數
參數 | 類型 |
---|---|
account | AdapterAccount |
回傳
Promise
<void
> | Awaitable
<undefined
| null
| AdapterAccount
>
listAuthenticatorsByUserId()?
optional listAuthenticatorsByUserId(userId): Awaitable<AdapterAuthenticator[]>
回傳來自使用者的所有驗證器。
如果找不到使用者,轉接器仍應回傳一個空陣列。如果因其他原因擷取失敗,轉接器必須拋出錯誤。
參數
參數 | 類型 |
---|---|
userId | string |
回傳
Awaitable
<AdapterAuthenticator
[]>
unlinkAccount()?
optional unlinkAccount(providerAccountId): Promise<void> | Awaitable<undefined | AdapterAccount>
參數
參數 | 類型 |
---|---|
providerAccountId | Pick <AdapterAccount , "provider" | "providerAccountId" > |
回傳
Promise
<void
> | Awaitable
<undefined
| AdapterAccount
>
待辦事項
目前尚未調用此方法。
updateAuthenticatorCounter()?
optional updateAuthenticatorCounter(credentialID, newCounter): Awaitable<AdapterAuthenticator>
更新驗證器的計數器。
如果更新失敗,轉接器必須拋出錯誤。
參數
參數 | 類型 |
---|---|
credentialID | string |
newCounter | 數字 |
回傳
Awaitable
<AdapterAuthenticator
>
updateSession()?
optional updateSession(session): Awaitable<undefined | null | AdapterSession>
更新資料庫中的 Session 並回傳。
另請參閱 資料庫會話管理
參數
參數 | 類型 |
---|---|
session | Partial <AdapterSession > & Pick <AdapterSession , "sessionToken" > |
回傳
Awaitable
<undefined
| null
| AdapterSession
>
updateUser()?
optional updateUser(user): Awaitable<AdapterUser>
更新資料庫中的使用者並回傳。
另請參閱 使用者管理
參數
參數 | 類型 |
---|---|
user | Partial <AdapterUser > & Pick <AdapterUser , "id" > |
回傳
useVerificationToken()?
optional useVerificationToken(params): Awaitable<null | VerificationToken>
從資料庫中回傳驗證令牌並刪除,使其只能使用一次。
另請參閱 驗證令牌
參數
參數 | 類型 |
---|---|
params | 物件 |
params.identifier | string |
params.token | string |
回傳
Awaitable
<null
| VerificationToken
>
AdapterAccount
帳號是使用者與提供者之間的連線。
帳號有兩種型態
- OAuth/OIDC 帳號,當使用者使用 OAuth 提供者登入時建立。
- 電子郵件帳號,當使用者使用電子郵件提供者登入時建立。
一個使用者可以有多個帳號。
繼承自
屬性
access_token?
optional readonly access_token: string;
繼承自
authorization_details?
optional readonly authorization_details: AuthorizationDetails[];
繼承自
expires_at?
optional expires_at: number;
根據 TokenEndpointResponse.expires_in 計算的值。
它是 TokenEndpointResponse.access_token 過期的絕對時間戳記(以秒為單位)。
此值可用於與 TokenEndpointResponse.refresh_token 一起實作令牌輪換。
請參閱
- https://authjs.dev.org.tw/guides/refresh-token-rotation#database-strategy
- https://www.rfc-editor.org/rfc/rfc6749#section-5.1
繼承自
expires_in?
optional readonly expires_in: number;
繼承自
id_token?
optional readonly id_token: string;
繼承自
provider
provider: string;
此帳號的提供者 ID。例如「google」。請參閱 https://authjs.dev.org.tw/reference/core/providers 的完整列表
繼承自
providerAccountId
providerAccountId: string;
此值取決於用於建立帳號的提供者類型。
- oauth/oidc:從
profile()
回呼函數傳回的 OAuth 帳號 ID。 - email:使用者的電子郵件地址。
- credentials:從
authorize()
回呼函數傳回的id
。
繼承自
refresh_token?
optional readonly refresh_token: string;
繼承自
scope?
optional readonly scope: string;
繼承自
token_type?
optional readonly token_type: Lowercase<string>;
注意:因為值不區分大小寫,所以始終以小寫形式傳回
繼承自
type
type: AdapterAccountType;
此帳號的提供者類型
覆寫
userId
userId: string;
此帳號所屬的使用者 ID
請參閱
https://authjs.dev.org.tw/reference/core/adapters#adapteruser
覆寫
AdapterAuthenticator
驗證器表示分配給使用者的憑證驗證器。
繼承自
屬性
計數器
counter: number;
驗證器被使用的次數。
繼承自
credentialBackedUp
credentialBackedUp: boolean;
客戶端驗證器是否備份了憑證。
繼承自
Authenticator
.credentialBackedUp
credentialDeviceType
credentialDeviceType: string;
驗證器的裝置類型。
繼承自
Authenticator
.credentialDeviceType
credentialID
credentialID: string;
Base64 編碼的憑證 ID。
繼承自
credentialPublicKey
credentialPublicKey: string;
Base64 編碼的憑證公鑰。
繼承自
Authenticator
.credentialPublicKey
providerAccountId
providerAccountId: string;
連接到驗證器的提供者帳戶 ID。
繼承自
Authenticator
.providerAccountId
transports?
optional transports: null | string;
串連的傳輸標誌。
繼承自
userId
userId: string;
驗證器的使用者 ID。
覆寫
AdapterSession
一個會話保留了關於使用者目前登入狀態的資訊。
屬性
expires
expires: Date;
會話過期的絕對日期。
如果在會話過期日期之前存取,它將根據 SessionOptions.maxAge
中定義的 maxAge
選項進行延長。它在 SessionOptions.updateAge
定義的期間內,永遠不會延長超過一次。
如果在會話過期日期之後存取,它將從資料庫中移除,以清理非使用中的會話。
sessionToken
sessionToken: string;
一個隨機產生的值,當使用 "database"
AuthConfig.strategy
選項時,用於在資料庫中查找會話。此值會儲存在客戶端安全、僅限 HTTP 的 Cookie 中。
userId
userId: string;
將活動會話連接到資料庫中的使用者
AdapterUser
使用者代表可以登入應用程式的人。如果使用者還不存在,當他們第一次登入時,會使用身分提供者返回的資訊(個人資料數據)來建立。也會建立對應的帳戶並連結到使用者。
擴展
屬性
email: string;
使用者的電子郵件地址。
覆寫
emailVerified
emailVerified: null | Date;
使用者是否已透過電子郵件提供者驗證其電子郵件地址。如果使用者尚未透過電子郵件提供者登入,則為 null
,或是第一次成功登入的日期。
id
id: string;
使用者的唯一識別碼。
覆寫
image?
optional image: null | string;
繼承自
name?
optional name: null | string;
繼承自
VerificationToken
驗證令牌是用於透過使用者的電子郵件地址登入使用者的臨時令牌。當使用者使用電子郵件提供者登入時建立。當使用者點擊電子郵件中的連結時,令牌和電子郵件會發送回伺服器,在那裡會將其雜湊並與資料庫中的值進行比較。如果令牌和電子郵件匹配,且令牌尚未過期,則使用者將登入。然後從資料庫中刪除令牌。
屬性
expires
expires: Date;
令牌過期的絕對日期。
identifier
identifier: string;
使用者的電子郵件地址。
token
token: string;
使用 AuthConfig.secret
值雜湊的令牌。
AdapterAccountType
type AdapterAccountType: Extract<ProviderType, "oauth" | "oidc" | "email" | "webauthn">;
帳戶的類型。
isDate()
isDate(value): value is string
判斷是否可以將給定的值解析為 Date
參數
參數 | 類型 |
---|---|
value | unknown |
返回
value is string