跳至內容
從 NextAuth.js v4 遷移?請閱讀 我們的遷移指南.
指南建立資料庫轉接器

建立資料庫轉接器

Auth.js 轉接器允許您與任何(甚至是多個)資料庫/後端服務整合,即使我們還沒有可用的官方套件。(我們歡迎針對新的轉接器提交 PR!請參閱下面的指南。)

Auth.js 轉接器非常靈活,您可以僅實作您需要的方法,並且僅建立實際會使用的資料庫表格/欄位。

Auth.js 轉接器是一個函式,它會接收一個 ORM/資料庫用戶端,並傳回一個物件,其中包含與資料庫互動的方法(基於Adapter 介面)。相同的資料庫轉接器將與任何 Auth.js 程式庫相容。

您可以選擇在您的轉接器上執行我們的轉接器測試,以確保它符合 Auth.js 的規定。

使用者管理

Auth.js 區分使用者和帳戶。一個使用者可以有多個帳戶。每個使用者首次登入的提供者類型都會建立一個帳戶。例如,如果使用者使用 Google 登入,然後使用 Facebook 登入,他們將會有兩個帳戶,每個提供者一個。使用者首次登入的提供者也會用於建立使用者物件。請參閱profile() 提供者方法

方法與模型

另請參閱:使用者帳戶模型。

雖然 Auth.js 沒有要求,但為了基本顯示目的,我們建議在 User 表格中新增以下欄位:nameemailimage。您可以使用profile() 提供者方法設定欄位。如果您不需要儲存這些屬性,請建立一個空的 profile() {} 方法。

雖然 Auth.js 沒有要求,但 Account 表格通常會儲存從提供者擷取的 Token。您可以使用account() 提供者方法設定欄位。如果您不需要儲存 Token,請建立一個空的 account() {} 方法。

資料庫 Session 管理

Auth.js 可以透過兩種方式管理 Session。請參閱概念:Session 策略,瞭解它們及其優缺點。

方法與模型

如果您想要使用資料庫 Session,您將需要實作以下方法

若要新增資料庫 Session 管理,您將需要如下擴充資料庫表格/欄位

另請參閱:Session 模型。

驗證 Token

當您想要支援電子郵件/無密碼登入時,Auth.js 會使用資料庫來儲存與使用者電子郵件地址相關聯的臨時驗證 Token。

方法與模型

另請參閱:驗證 Token 模型。

官方轉接器指南

完成以下所有步驟後,您就可以將 PR 提交到我們的儲存庫

如果您建立了一個轉接器,並希望我們將其作為官方套件發佈,請確保它符合以下要求。請查看此現有的轉接器,以瞭解套件結構、所需檔案、測試設定、組態等。

  1. 轉接器必須實作Adapter 介面的所有方法

  2. 必須包含轉接器測試,並且必須通過。Docker 比服務更受青睞,以使 CI 對網路錯誤具有彈性,並減少 GitHub Action Secrets 的數量(這也讓我們可以在 Fork PR 中執行這些測試)

  3. 轉接器必須遵循以下編碼風格

    • 以 TypeScript 編寫
    • 通過 Monorepo 的 Linting 規則
    • 不包含 Polyfill
    • 設定為 ES 模組 (ESM)
    • 透過 JSDoc 註解記錄
    • 至少有一個具名匯出,從其主要模組匯出。(例如 export function MyAdapter(): Adapter {})
    • 集合/表格名稱應遵循底層 ORM/資料庫文件/慣例的慣例(複數/單數、camelCase/snake_case)
  4. 設定 Monorepo 以協助我們維護套件

  5. 轉接器必須能夠處理來自使用者的任何屬性

    ORM/資料庫用戶端可能有其自己的資料類型,但 Auth.js 希望這些類型能夠標準化為純 JavaScript 物件以保持一致性。如果您的 ORM/資料庫用戶端不會自動轉換,您需要在從/向資料庫讀取/寫入值時轉換這些值。

    您可能會想檢查屬性的名稱並根據名稱進行轉換,但這並不可擴展(例如:User 物件可能有多個 Date 屬性,而不僅僅是 emailVerified)。

    我們建議您建立轉換數值的工具函式。以下是如何轉換日期的範例(如果您的 ORM/資料庫客戶端使用其他資料類型,請記得也要轉換它們,而不僅僅是日期)。它會檢查該值是否可以解析為日期,如果可以,則將其轉換為 Date 物件。否則,它會保留原始值不變。

// https://github.com/honeinc/is-iso-date/blob/8831e79b5b5ee615920dcb350a355ffc5cbf7aed/index.js#L5
const isoDateRE =
  /(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))/
 
const isDate = (val: any): val is ConstructorParameters<typeof Date>[0] =>
  !!(val && isoDateRE.test(val) && !isNaN(Date.parse(val)))
 
export const format = {
  /** Takes an object that's coming from a database and converts it to plain JavaScript. */
  from<T>(object: Record<string, any> = {}): T {
    const newObject: Record<string, unknown> = {}
    for (const [key, value] of Object.entries(object))
      if (isDate(value)) newObject[key] = new Date(value)
      else newObject[key] = value
    return newObject as T
  },
  /** Takes an object that's coming from Auth.js and prepares it to be written to the database. */
  to<T>(object: Record<string, any>): T {
    const newObject: Record<string, unknown> = {}
    for (const [key, value] of Object.entries(object))
      if (value instanceof Date) newObject[key] = value.toISOString()
      else newObject[key] = value
    return newObject as T
  },
}

TypeScript

您可以利用框架套件所提供的類型(例如,next-auth/adapters@auth/sveltekit/adapters)。

import type { Adapter } from "next-auth/adapters"
 
function MyAdapter(): Adapter {
  return {
    // your adapter methods here
  }
}

當您在 JavaScript 中編寫您的 Adapter 時,您仍然可以使用 JSDoc 來獲得有用的編輯器提示和自動完成功能。

/** @return { import("next-auth/adapters").Adapter } */
function MyAdapter() {
  return {
    // your adapter methods here
  }
}

資源

Auth.js © Balázs Orbán 及團隊 -2024