Skip to content

基础认证守卫

基础认证守卫是 HTTP 认证框架 的实现,客户端必须通过 Authorization 头以 base64 编码字符串的形式传递用户凭证。如果凭证有效,服务器将允许请求。否则,将显示原生浏览器提示框以重新输入凭证。

配置守卫

认证守卫在 config/auth.ts 文件中定义。您可以在此文件的 guards 对象下配置多个守卫。

ts
import { defineConfig } from '@adonisjs/auth'
// highlight-start
import { basicAuthGuard, basicAuthUserProvider } from '@adonisjs/auth/basic_auth'
// highlight-end

const authConfig = defineConfig({
  default: 'basicAuth',
  guards: {
    // highlight-start
    basicAuth: basicAuthGuard({
      provider: basicAuthUserProvider({
        model: () => import('#models/user'),
      }),
    })
    // highlight-end
  },
})

export default authConfig

basicAuthGuard 方法创建 BasicAuthGuard 类的实例。它接受一个用户提供器,可用于在认证期间查找用户。

basicAuthUserProvider 方法创建 BasicAuthLucidUserProvider 类的实例。它接受用于验证用户凭证的模型引用。

准备 User 模型

basicAuthUserProvider 一起配置的模型(本例中为 User 模型)必须使用 AuthFinder mixin 以在认证期间验证用户凭证。

ts
import { DateTime } from 'luxon'
import { compose } from '@adonisjs/core/helpers'
import { BaseModel, column } from '@adonisjs/lucid/orm'
// highlight-start
import hash from '@adonisjs/core/services/hash'
import { withAuthFinder } from '@adonisjs/auth/mixins/lucid'
// highlight-end

// highlight-start
const AuthFinder = withAuthFinder(() => hash.use('scrypt'), {
  uids: ['email'],
  passwordColumnName: 'password',
})
// highlight-end

// highlight-start
export default class User extends compose(BaseModel, AuthFinder) {
  // highlight-end
  @column({ isPrimary: true })
  declare id: number

  @column()
  declare fullName: string | null

  @column()
  declare email: string

  @column()
  declare password: string

  @column.dateTime({ autoCreate: true })
  declare createdAt: DateTime

  @column.dateTime({ autoCreate: true, autoUpdate: true })
  declare updatedAt: DateTime
}

保护路由

配置完守卫后,您可以使用 auth 中间件来保护路由免受未认证请求。该中间件在 start/kernel.ts 文件的命名中间件集合中注册。

ts
import router from '@adonisjs/core/services/router'

export const middleware = router.named({
  auth: () => import('#middleware/auth_middleware')
})
ts
// highlight-start
import { middleware } from '#start/kernel'
// highlight-end
import router from '@adonisjs/core/services/router'

router
  .get('dashboard', ({ auth }) => {
    return auth.user
  })
  .use(middleware.auth({
    // highlight-start
    guards: ['basicAuth']
    // highlight-end
  }))

处理认证异常

如果用户未认证,auth 中间件会抛出 E_UNAUTHORIZED_ACCESS 异常。该异常会自动转换为带有 WWW-Authenticate 头的 HTTP 响应。WWW-Authenticate 头会发起认证质询,并触发原生浏览器提示框以重新输入凭证。

获取已认证用户

您可以使用 auth.user 属性访问已登录用户实例。由于您使用了 auth 中间件,auth.user 属性将始终可用。

ts
import { middleware } from '#start/kernel'
import router from '@adonisjs/core/services/router'

router
  .get('dashboard', ({ auth }) => {
    return `您已认证为 ${auth.user!.email}`
  })
  .use(middleware.auth({
    guards: ['basicAuth']
  }))

获取已认证用户或失败

如果您不喜欢在 auth.user 属性上使用非空断言运算符,您可以使用 auth.getUserOrFail 方法。此方法将返回用户对象或抛出 E_UNAUTHORIZED_ACCESS 异常。

ts
import { middleware } from '#start/kernel'
import router from '@adonisjs/core/services/router'

router
  .get('dashboard', ({ auth }) => {
    // highlight-start
    const user = auth.getUserOrFail()
    return `您已认证为 ${user.email}`
    // highlight-end
  })
  .use(middleware.auth({
    guards: ['basicAuth']
  }))