跳至内容
从 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.js.cn/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

提供者配置

除非您在不同的路径上安装 ExpressAuth 处理程序,否则 提供者 使用的回调 URL 必须设置为以下内容:

[origin]/auth/callback/[provider]

登录和注销

一旦您的应用程序被安装,您就可以通过从客户端代码向以下 REST API 端点 发出请求来登录或注销。注意:请确保在所有登录和注销请求的请求正文中包含 csrfToken

管理会话

如果您使用的是带有模板引擎的 Express(例如 EJS、Pug),您可以通过以下方式使用中间件将会话数据提供给所有路由:

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;
};
类型声明
错误?
optional err: Error;
覆盖

Error.cause

消息

message: string;
继承自

Error.message

名称

name: string;
继承自

Error.name

堆栈?

optional stack: string;
继承自

Error.stack

类型

type: ErrorType;

错误类型。用于在日志中识别错误。

prepareStackTrace()?

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

格式化堆栈跟踪的可选覆盖

参见

https://v8.node.org.cn/docs/stack-trace-api#customizing-stack-traces

参数
参数类型
errError
堆栈跟踪CallSite[]
返回

任何

继承自

Error.prepareStackTrace

stackTraceLimit

static stackTraceLimit: number;
继承自

Error.stackTraceLimit

方法

captureStackTrace()

static captureStackTrace(targetObject, constructorOpt?): void

在目标对象上创建 .stack 属性

参数
参数类型
targetObject对象
constructorOpt?功能
返回

无效

继承自

Error.captureStackTrace


CredentialsSignin

可以从 Credentials 提供程序的 authorize 回调中抛出。当在 authorize 回调中发生错误时,会发生两件事

  1. 用户被重定向到登录页面,URL 中带有 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: string;

在重定向 URL 的 code 查询参数中设置的错误代码。

⚠ 注意:此属性将包含在 URL 中,因此请确保它不会暗示敏感错误。

如果需要调试,完整的错误始终记录在服务器上。

通常,我们不建议特别暗示用户是否使用了错误的用户名或密码,而是尝试使用“无效凭据”之类的内容。

消息

message: string;
继承自

SignInError.message

名称

name: string;
继承自

SignInError.name

堆栈?

optional stack: string;
继承自

SignInError.stack

类型

type: ErrorType;

错误类型。用于在日志中识别错误。

继承自

SignInError.type

种类

static kind: string;
继承自

SignInError.kind

prepareStackTrace()?

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

格式化堆栈跟踪的可选覆盖

参见

https://v8.node.org.cn/docs/stack-trace-api#customizing-stack-traces

参数
参数类型
errError
堆栈跟踪CallSite[]
返回

任何

继承自

SignInError.prepareStackTrace

stackTraceLimit

static stackTraceLimit: number;
继承自

SignInError.stackTraceLimit

类型

static type: string;

方法

captureStackTrace()

static captureStackTrace(targetObject, constructorOpt?): void

在目标对象上创建 .stack 属性

参数
参数类型
targetObject对象
constructorOpt?功能
返回

无效

继承自

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: string;

此帐户的提供程序 ID。例如,“google”。在 https://authjs.oauth.ac.cn/reference/core/providers 查看完整列表

providerAccountId

providerAccountId: string;

此值取决于用于创建帐户的提供程序类型。

  • oauth/oidc:OAuth 帐户的 ID,从 profile() 回调返回。
  • 电子邮件:用户的电子邮件地址。
  • 凭据:从 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.oauth.ac.cn/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

Indexable

[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 函数。使用不当会导致安全问题。

它可用于支持企业代理、自定义 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

返回

功能

参数

参数类型
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