简介

身份认证

AdonisJS 自带一套健壮且安全的身份认证系统,可用于登录并认证应用的用户。无论是服务端渲染的应用、SPA 客户端还是移动应用,你都可以为它们配置身份认证。

身份认证软件包围绕**守卫(guards)提供器(providers)**构建。

  • 守卫是某种特定登录方式的端到端实现。例如,session 守卫允许你使用 cookie 和会话来认证用户;而 access_tokens 守卫则允许你使用令牌(token)来认证客户端。

  • 提供器(providers)用于从数据库中查找用户和令牌。你可以使用内置的提供器,也可以实现自己的提供器。

为保障应用的安全,我们会对用户密码和令牌进行恰当的哈希处理。此外,AdonisJS 的安全原语能够防范时序攻击(timing attack)会话固定攻击(session fixation attacks)

Auth 软件包不支持的功能

auth 软件包专注于认证 HTTP 请求,以下功能不在其范围内。

  • 用户注册相关功能,如注册表单邮箱验证账户激活
  • 账户管理相关功能,如密码找回邮箱更新
  • 分配角色或验证权限。相反,请使用 bouncer 在你的应用中实现授权检查。

选择合适的身份认证守卫

以下内置的身份认证守卫为你提供了最直接的工作流,在保障应用安全的同时完成用户认证。此外,你也可以为自定义需求构建自己的身份认证守卫

会话守卫(Session)

会话守卫使用 @adonisjs/session 软件包来在会话存储中跟踪已登录用户的状态。

会话和 cookie 已在互联网上存在很长时间,并且对大多数应用来说都表现良好。我们推荐使用会话守卫:

  • 如果你正在创建一个服务端渲染的 Web 应用。
  • 或者,一个客户端与 AdonisJS API 位于同一顶级域下的 AdonisJS API。例如,api.example.comexample.com

访问令牌守卫(Access tokens)

访问令牌(access tokens)是在登录成功后颁发给用户的加密安全随机令牌(也称为不透明访问令牌,Opaque access tokens)。你可以将访问令牌用于那些 AdonisJS 服务器无法写入/读取 cookie 的应用。例如:

  • 原生移动应用。
  • 托管在与你的 AdonisJS API 服务器不同域名上的 Web 应用。

使用访问令牌时,安全地存储它们是客户端应用的责任。访问令牌提供了对你的应用(以用户身份)的无限制访问,一旦泄漏可能导致安全问题。

基础认证守卫(Basic auth)

基础认证守卫是 HTTP 认证框架 的一种实现,客户端必须通过 Authorization 请求头以 base64 编码字符串的形式传递用户凭据。

相比于基础认证,有更好的方式来实现安全的登录系统。不过,在应用处于活跃开发阶段时,你可以临时使用它。

选择用户提供器

正如本指南前面所述,用户提供器(user provider)负责在身份认证过程中查找用户。

用户提供器是与守卫相关的;例如,会话守卫的用户提供器负责通过用户 ID 查找用户,而访问令牌守卫的用户提供器还负责验证访问令牌。

我们为内置守卫提供了一个 Lucid 用户提供器,它使用 Lucid 模型来查找用户、生成令牌以及验证令牌。

安装

auth 系统已预先配置在 webapi 启动套件中。不过,你也可以按照以下方式在应用中手动安装并配置它。

# 使用会话守卫配置(默认)
node ace add @adonisjs/auth --guard=session
# 使用访问令牌守卫配置
node ace add @adonisjs/auth --guard=access_tokens
# 使用基础认证守卫配置
node ace add @adonisjs/auth --guard=basic_auth
  1. 使用检测到的包管理器安装 @adonisjs/auth 软件包。

  2. adonisrc.ts 文件中注册以下服务提供者。

    {
    providers: [
    // ...其他 providers
    () => import('@adonisjs/auth/auth_provider')
    ]
    }
  3. start/kernel.ts 文件中创建并注册以下中间件。

    router.use([
    () => import('@adonisjs/auth/initialize_auth_middleware')
    ])
    router.named({
    auth: () => import('#middleware/auth_middleware'),
    // 仅在使用会话守卫时
    guest: () => import('#middleware/guest_middleware')
    })
  4. app/models 目录下创建用户模型。

  5. users 表创建数据库迁移。

  6. 为所选守卫创建数据库迁移。

初始化身份认证中间件(Initialize auth middleware)

在设置过程中,我们会在你的应用中注册 @adonisjs/auth/initialize_auth_middleware。该中间件负责创建 Authenticator 类的实例,并通过 ctx.auth 属性将其共享给请求的其余部分。

请注意,初始化身份认证中间件不会对请求进行认证,也不会保护路由。它仅用于初始化认证器(authenticator)并将其共享给请求的其余部分。你必须使用 auth 中间件来保护路由。

同时,同一个认证器实例也会共享给 Edge 模板(如果你的应用使用了 Edge),你可以通过 auth 属性访问它。例如:

@if(auth.isAuthenticated)
<p> Hello {{ auth.user.email }} </p>
@end

创建 users 表

configure 命令会在 database/migrations 目录下为 users 表创建一份数据库迁移。你可以自由打开该文件,并根据你的应用需求进行修改。

默认情况下,会创建以下列。

import { BaseSchema } from '@adonisjs/lucid/schema'
export default class extends BaseSchema {
protected tableName = 'users'
async up() {
this.schema.createTable(this.tableName, (table) => {
table.increments('id').notNullable()
table.string('full_name').nullable()
table.string('email', 254).notNullable().unique()
table.string('password').notNullable()
table.timestamp('created_at').notNullable()
table.timestamp('updated_at').nullable()
})
}
async down() {
this.schema.dropTable(this.tableName)
}
}

此外,如果你对 users 表定义、重命名或删除了列,请更新 User 模型。

下一步