跳至內容
要從 NextAuth.js v4 遷移嗎?請閱讀 我們的遷移指南.
API 參考@auth/express

@auth/express

⚠️

@auth/express 目前處於實驗階段。API 未來會變更。

Express Auth 是 Auth.js 的官方 Express 整合。它提供了一種簡單的方法,只需幾行程式碼即可將驗證新增至您的 Express 應用程式。

安裝

npm install @auth/express

使用方式

src/routes/auth.route.ts
import { ExpressAuth } from "@auth/express"
import GitHub from "@auth/express/providers/github"
import express from "express"
 
const app = express()
 
// If app is served through a proxy, trust the proxy to allow HTTPS protocol to be detected
// https://express.dev.org.tw/en/guide/behind-proxies.html
app.set('trust proxy', true)
app.use("/auth/*", ExpressAuth({ providers: [ GitHub ] }))

別忘了設定 AUTH_SECRET 環境變數。這應該是一個至少 32 個字元的隨機字串。在 UNIX 系統上,您可以使用 openssl rand -hex 32 或查看 https://generate-secret.vercel.app/32

您還需要將環境變數載入您的執行環境。例如,在 Node.js 中,使用像 dotenv 或在 Deno 中使用 Deno.env 等套件。

提供者設定

提供者使用的回呼 URL 必須設定為以下值,除非您在不同的路徑上掛載 ExpressAuth 處理程式

[origin]/auth/callback/[provider]

登入和登出

一旦您的應用程式掛載完成,您可以從用戶端程式碼向以下 REST API 端點發出請求來登入或登出。注意:請務必在所有登入和登出請求的請求主體中包含 csrfToken

管理工作階段

如果您使用具有範本引擎(例如 EJS、Pug)的 Express,您可以透過中介軟體,讓所有路由都能使用工作階段資料,如下所示

app.ts
import { getSession } from "@auth/express"
 
export function authSession(req: Request, res: Response, next: NextFunction) {
  res.locals.session = await getSession(req)
  next()
}
 
app.use(authSession)
 
// Now in your route
app.get("/", (req, res) => {
  const { session } = res.locals
  res.render("index", { user: session?.user })
})

授權

您可以透過檢查是否存在工作階段來保護路由,如果不存在工作階段,則重新導向至登入頁面。這可以針對每個路由執行,也可以使用以下中介軟體針對一組路由執行

export async function authenticatedUser(
  req: Request,
  res: Response,
  next: NextFunction
) {
  const session = res.locals.session ?? (await getSession(req, authConfig))
  if (!session?.user) {
    res.redirect("/login")
  } else {
    next()
  }
}

每個路由

若要保護單一路由,只需將中介軟體新增至路由,如下所示

app.ts
// This route is protected
app.get("/profile", authenticatedUser, (req, res) => {
  const { session } = res.locals
  res.render("profile", { user: session?.user })
})
 
// This route is not protected
app.get("/", (req, res) => {
  res.render("index")
})
 
app.use("/", root)

每組路由

若要保護一組路由,請定義一個路由器,並將中介軟體新增至路由器,如下所示

routes/protected.route.ts
import { Router } from "express"
 
const router = Router()
 
router.use(authenticatedUser) // All routes defined after this will be protected
 
router.get("/", (req, res) => {
  res.render("protected")
})
 
export default router

然後,我們掛載路由器,如下所示

app.ts
import protected from "./routes/protected.route"
 
app.use("/protected", protected)

關於 ESM 的注意事項

@auth/express 僅限 ESM。這表示您的 package.json 必須包含 "type": "module",而 tsconfig.json 應包含 "module": "NodeNext"ESNext。檔案匯入必須使用 .js 副檔名,例如 import { MyRouter } from "./my-router.js"

您的開發伺服器應使用 tsx 搭配 tsx index.ts(快速啟動,沒有類型檢查)或 ts-node 搭配「node --loader ts-node/esm index.ts」(啟動較慢,但有類型檢查)來執行。

雖然不建議這麼做,但如果您希望在 CommonJS 專案中使用 @auth/express 而不遷移和進行上述變更,則可以使用 tsx 執行開發伺服器,並且可以使用 pkgroll 進行編譯。將 ‘“name”: ”./dist/index.js”’ 或 ‘“name”: ”./dist/index.mjs”’ 新增至您的 package.json,並執行 ‘pkgroll’ 以使用 ESM 和 CommonJS 支援進行編譯。對於新專案,建議直接使用 ESM。

AuthError

所有 Auth.js 錯誤的基本錯誤類別。它經過最佳化,可透過 logger.error 選項,以格式良好的方式印在伺服器記錄中。

擴展

建構子

new AuthError(message, errorOptions)

new AuthError(message?, errorOptions?): AuthError
參數
參數類型
message?string | ErrorOptions
errorOptions?ErrorOptions
回傳

AuthError

覆寫

Error.constructor

屬性

cause?

optional cause: Record<string, unknown> & {
  err: Error;
};
類型宣告
err?
optional err: Error;
覆寫

Error.cause

message

message: string;
繼承自

Error.message

name

name: string;
繼承自

Error.name

stack?

optional stack: string;
繼承自

Error.stack

type

type: ErrorType;

錯誤類型。用於在日誌中識別錯誤。

prepareStackTrace()?

static optional prepareStackTrace: (err, stackTraces) => any;

用於格式化堆疊追蹤的可選覆寫

請參閱

https://v8.dev.org.tw/docs/stack-trace-api#customizing-stack-traces

參數
參數類型
err錯誤
stackTracesCallSite[]
回傳

any

繼承自

Error.prepareStackTrace

stackTraceLimit

static stackTraceLimit: number;
繼承自

Error.stackTraceLimit

方法

captureStackTrace()

static captureStackTrace(targetObject, constructorOpt?): void

在目標物件上建立 .stack 屬性

參數
參數類型
targetObjectobject
constructorOpt?Function
回傳

void

繼承自

Error.captureStackTrace


CredentialsSignin

可以從 Credentials 提供者的 authorize 回呼中拋出。當 authorize 回呼期間發生錯誤時,可能會發生兩種情況

  1. 使用者會被重新導向到登入頁面,網址中帶有 error=CredentialsSignin&code=credentialscode 是可設定的。
  2. 如果您在處理表單動作的伺服器端框架中拋出此錯誤,則會拋出此錯誤,而不是重新導向使用者,因此您需要處理。

繼承自

建構子

new CredentialsSignin(message, errorOptions)

new CredentialsSignin(message?, errorOptions?): CredentialsSignin
參數
參數類型
message?string | ErrorOptions
errorOptions?ErrorOptions
回傳

CredentialsSignin

繼承自

SignInError.constructor

屬性

cause?

optional cause: Record<string, unknown> & {
  err: Error;
};
類型宣告
err?
optional err: Error;
繼承自

SignInError.cause

code

code: string;

在重新導向網址的 code 查詢參數中設定的錯誤代碼。

⚠ 注意:此屬性將會包含在網址中,因此請確保它不會暗示敏感錯誤。

如果需要除錯,完整的錯誤始終記錄在伺服器上。

一般而言,我們不建議明確提示使用者是否有錯誤的使用者名稱或密碼,請嘗試使用「無效的憑證」之類的提示。

message

message: string;
繼承自

SignInError.message

name

name: string;
繼承自

SignInError.name

stack?

optional stack: string;
繼承自

SignInError.stack

type

type: ErrorType;

錯誤類型。用於在日誌中識別錯誤。

繼承自

SignInError.type

kind

static kind: string;
繼承自

SignInError.kind

prepareStackTrace()?

static optional prepareStackTrace: (err, stackTraces) => any;

用於格式化堆疊追蹤的可選覆寫

請參閱

https://v8.dev.org.tw/docs/stack-trace-api#customizing-stack-traces

參數
參數類型
err錯誤
stackTracesCallSite[]
回傳

any

繼承自

SignInError.prepareStackTrace

stackTraceLimit

static stackTraceLimit: number;
繼承自

SignInError.stackTraceLimit

type

static type: string;

方法

captureStackTrace()

static captureStackTrace(targetObject, constructorOpt?): void

在目標物件上建立 .stack 屬性

參數
參數類型
targetObjectobject
constructorOpt?Function
回傳

void

繼承自

SignInError.captureStackTrace


帳號

通常包含有關正在使用的提供者的資訊,並且還擴展了 TokenSet,這是 OAuth 提供者返回的不同權杖。

繼承自

屬性

access_token?

optional readonly access_token: string;
繼承自

Partial.access_token

authorization_details?

optional readonly authorization_details: AuthorizationDetails[];
繼承自

Partial.authorization_details

expires_at?

optional expires_at: number;

基於 TokenEndpointResponse.expires_in 計算的值。

它是 TokenEndpointResponse.access_token 過期的絕對時間戳記(以秒為單位)。

此值可用於實作權杖輪換以及 TokenEndpointResponse.refresh_token。

請參閱

expires_in?

optional readonly expires_in: number;
繼承自

Partial.expires_in

id_token?

optional readonly id_token: string;
繼承自

Partial.id_token

provider

provider: string;

此帳號的提供者 ID。例如:「google」。請參閱 https://authjs.dev.org.tw/reference/core/providers 的完整清單

providerAccountId

providerAccountId: string;

此值取決於用於建立帳號的提供者類型。

  • oauth/oidc:OAuth 帳號的 ID,從 profile() 回呼中傳回。
  • email:使用者的電子郵件地址。
  • 憑證:從 authorize() 回呼函式返回的 id

refresh_token?

optional readonly refresh_token: string;
繼承自

Partial.refresh_token

scope?

optional readonly scope: string;
繼承自

Partial.scope

token_type?

optional readonly token_type: Lowercase<string>;

注意:由於此值不區分大小寫,因此一律以小寫形式返回。

繼承自

Partial.token_type

type

type: ProviderType;

此帳戶的供應商類型

userId?

optional userId: string;

此帳戶所屬使用者的 ID

請參閱

https://authjs.dev.org.tw/reference/core/adapters#adapteruser


DefaultSession

擴展自

屬性

expires

expires: string;

user?

optional user: User;

Profile

從您的 OAuth 供應商返回的使用者資訊。

請參閱

https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims

可索引

[claim: string]: unknown

屬性

address?

optional address: null | {
  country: null | string;
  formatted: null | string;
  locality: null | string;
  postal_code: null | string;
  region: null | string;
  street_address: null | string;
};

birthdate?

optional birthdate: null | string;

email?

optional email: null | string;

email_verified?

optional email_verified: null | boolean;

family_name?

optional family_name: null | string;

gender?

optional gender: null | string;

given_name?

optional given_name: null | string;

id?

optional id: null | string;

locale?

optional locale: null | string;

middle_name?

optional middle_name: null | string;

name?

optional name: null | string;

nickname?

optional nickname: null | string;

phone_number?

optional phone_number: null | string;

picture?

optional picture: any;

preferred_username?

optional preferred_username: null | string;

profile?

optional profile: null | string;

sub?

optional sub: null | string;

updated_at?

optional updated_at: null | string | number | Date;

website?

optional website: null | string;

zoneinfo?

optional zoneinfo: null | string;

Session

已登入使用者的活動工作階段。

擴展自

屬性

expires

expires: string;
繼承自

DefaultSession.expires

user?

optional user: User;
繼承自

DefaultSession.user


User

OAuth 供應商的 profile 回呼函式中傳回的物件形狀,可在 jwtsession 回呼函式中使用,或在使用資料庫時,可在 session 回呼函式的第二個參數中使用。

擴展自

屬性

email?

optional email: null | string;

id?

optional id: string;

image?

optional image: null | string;

name?

optional name: null | string;

ExpressAuthConfig

type ExpressAuthConfig: Omit<AuthConfig, "raw">;

GetSessionResult

type GetSessionResult: Promise<Session | null>;

customFetch

const customFetch: unique symbol;
🚫

此選項可讓您覆寫供應商用來直接向供應商的 OAuth 端點發出請求的預設 fetch 函式。不正確的使用可能會產生安全性隱憂。

它可用於支援企業 Proxy、自訂 fetch 程式庫、快取探索端點、為測試新增模擬、記錄、為不符合規格的供應商設定自訂標頭/參數等。

範例

import { Auth, customFetch } from "@auth/core"
import GitHub from "@auth/core/providers/github"
 
const dispatcher = new ProxyAgent("my.proxy.server")
function proxy(...args: Parameters<typeof fetch>): ReturnType<typeof fetch> {
  return undici(args[0], { ...(args[1] ?? {}), dispatcher })
}
 
const response = await Auth(request, {
  providers: [GitHub({ [customFetch]: proxy })]
})

請參閱


ExpressAuth()

ExpressAuth(config): (req, res, next) => Promise<void>

參數

參數類型
configExpressAuthConfig

返回

Function

參數

參數類型
reqRequest<ParamsDictionary, any, any, ParsedQs, Record<string, any>>
resResponse<any, Record<string, any>>
nextNextFunction

返回

Promise<void>


getSession()

getSession(req, config): GetSessionResult

參數

參數類型
reqRequest<ParamsDictionary, any, any, ParsedQs, Record<string, any>>
configExpressAuthConfig

返回

GetSessionResult

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