Basic Auth 守卫

基础认证守卫(Basic authentication guard)

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

配置守卫

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

import { defineConfig } from '@adonisjs/auth'
import { basicAuthGuard, basicAuthUserProvider } from '@adonisjs/auth/basic_auth'
const authConfig = defineConfig({
default: 'basicAuth',
guards: {
basicAuth: basicAuthGuard({
provider: basicAuthUserProvider({
model: () => import('#models/user'),
}),
})
},
})
export default authConfig

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

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

准备 User 模型

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

import { DateTime } from 'luxon'
import { compose } from '@adonisjs/core/helpers'
import { BaseModel, column } from '@adonisjs/lucid/orm'
import hash from '@adonisjs/core/services/hash'
import { withAuthFinder } from '@adonisjs/auth/mixins/lucid'
const AuthFinder = withAuthFinder(() => hash.use('scrypt'), {
uids: ['email'],
passwordColumnName: 'password',
})
export default class User extends compose(BaseModel, AuthFinder) {
@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 文件中以命名中间件集合的形式注册。

import router from '@adonisjs/core/services/router'
export const middleware = router.named({
auth: () => import('#middleware/auth_middleware')
})
import { middleware } from '#start/kernel'
import router from '@adonisjs/core/services/router'
router
.get('dashboard', ({ auth }) => {
return auth.user
})
.use(middleware.auth({
guards: ['basicAuth']
}))

处理身份认证异常

如果用户未通过认证,auth 中间件会抛出 E_UNAUTHORIZED_ACCESS 异常。该异常会被自动转换为带有响应中 WWW-Authenticate 请求头的 HTTP 响应。WWW-Authenticate 会对认证发起挑战,并触发一个原生的 Web 提示框来重新输入凭据。

获取已认证用户

你可以使用 auth.user 属性访问已登录用户的实例。由于你正在使用 auth 中间件,auth.user 属性始终可用。

import { middleware } from '#start/kernel'
import router from '@adonisjs/core/services/router'
router
.get('dashboard', ({ auth }) => {
return `You are authenticated as ${auth.user!.email}`
})
.use(middleware.auth({
guards: ['basicAuth']
}))

获取已认证用户,否则失败

如果你不喜欢在 auth.user 属性上使用非空断言运算符(non-null assertion operator),你可以使用 auth.getUserOrFail 方法。该方法会返回用户对象,否则抛出 E_UNAUTHORIZED_ACCESS 异常。

import { middleware } from '#start/kernel'
import router from '@adonisjs/core/services/router'
router
.get('dashboard', ({ auth }) => {
const user = auth.getUserOrFail()
return `You are authenticated as ${user.email}`
})
.use(middleware.auth({
guards: ['basicAuth']
}))