You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于AdonisJS V6的多模型身份认证实现需求

AdonisJS V6 多模型认证(User/Admin分离)实现步骤

以下是针对AdonisJS V6(@adonisjs/core": "^6.17.2")和@adonisjs/auth": "^9.3.1"版本的多模型认证实现方案,完全分离User和Admin两个独立模型的认证流程:

1. 修改认证配置文件(config/auth.ts)

在配置文件中分别定义守卫(Guards)和提供者(Providers),对应User和Admin模型:

import { defineConfig } from '@adonisjs/auth'
import { InferAuthEvents, Authenticators } from '@adonisjs/auth/types'

const authConfig = defineConfig({
  default: 'user', // 默认守卫,可按需调整
  guards: {
    // User模型对应的JWT守卫
    user: {
      driver: 'jwt',
      publicKey: env.get('JWT_PUBLIC_KEY'),
      privateKey: env.get('JWT_PRIVATE_KEY'),
      provider: {
        driver: 'lucid',
        identifierKey: 'id',
        uids: ['email'],
        model: () => import('#models/user'),
      },
      tokenProvider: {
        type: 'api',
        driver: 'database',
        table: 'auth_tokens',
      },
      expiresIn: '30d',
    },
    // Admin模型对应的JWT守卫
    admin: {
      driver: 'jwt',
      publicKey: env.get('JWT_PUBLIC_KEY'),
      privateKey: env.get('JWT_PRIVATE_KEY'),
      provider: {
        driver: 'lucid',
        identifierKey: 'id',
        uids: ['email'],
        model: () => import('#models/admin'),
      },
      tokenProvider: {
        type: 'api',
        driver: 'database',
        table: 'auth_tokens', // 可共用表,也可单独创建admin_auth_tokens表
      },
      expiresIn: '7d',
    },
  },
})

export default authConfig
export type AuthenticatorKeys = keyof Authenticators<typeof authConfig>
export type AuthEvents = InferAuthEvents<typeof authConfig>

2. 为模型添加认证特质

User模型(app/Models/User.ts)

实现认证契约并添加HasAuthTokens特质:

import { DateTime } from 'luxon'
import { BaseModel, column } from '@adonisjs/lucid/orm'
import { hash } from '@adonisjs/core/services'
import { Authenticatable, AuthenticatableContract, HasAuthTokens } from '@adonisjs/auth/mixins'

const AuthMixin = Authenticatable(() => import('@adonisjs/auth'), {
  passwordColumnName: 'password',
})

export default class User extends BaseModel implements AuthenticatableContract {
  @column({ isPrimary: true })
  public id: number

  @column()
  public email: string

  @column({ serializeAs: null })
  public password: string

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

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

  // 混入认证相关方法
  public static super = AuthMixin(User)
  public $hasAuthTokens = HasAuthTokens

  @column.dateTime()
  public passwordChangedAt: DateTime | null

  public async verifyPassword(password: string): Promise<boolean> {
    return hash.verify(this.password, password)
  }
}

Admin模型(app/Models/Admin.ts)

同样配置认证特质:

import { DateTime } from 'luxon'
import { BaseModel, column } from '@adonisjs/lucid/orm'
import { hash } from '@adonisjs/core/services'
import { Authenticatable, AuthenticatableContract, HasAuthTokens } from '@adonisjs/auth/mixins'

const AuthMixin = Authenticatable(() => import('@adonisjs/auth'), {
  passwordColumnName: 'password',
})

export default class Admin extends BaseModel implements AuthenticatableContract {
  @column({ isPrimary: true })
  public id: number

  @column()
  public email: string

  @column({ serializeAs: null })
  public password: string

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

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

  public static super = AuthMixin(Admin)
  public $hasAuthTokens = HasAuthTokens

  @column.dateTime()
  public passwordChangedAt: DateTime | null

  public async verifyPassword(password: string): Promise<boolean> {
    return hash.verify(this.password, password)
  }
}

3. 创建认证控制器

用户登录控制器(app/Controllers/Http/UserAuthController.ts)

import type { HttpContext } from '@adonisjs/core/http'

export default class UserAuthController {
  async login({ request, auth, response }: HttpContext) {
    const { email, password } = request.only(['email', 'password'])

    try {
      // 使用user守卫验证并生成token
      const token = await auth.use('user').attempt(email, password)
      return response.ok({ token, user: token.user })
    } catch {
      return response.unauthorized('邮箱或密码错误')
    }
  }

  async logout({ auth, response }: HttpContext) {
    await auth.use('user').revoke()
    return response.ok({ message: '用户已退出登录' })
  }
}

管理员登录控制器(app/Controllers/Http/AdminAuthController.ts)

import type { HttpContext } from '@adonisjs/core/http'

export default class AdminAuthController {
  async login({ request, auth, response }: HttpContext) {
    const { email, password } = request.only(['email', 'password'])

    try {
      // 使用admin守卫验证并生成token
      const token = await auth.use('admin').attempt(email, password)
      return response.ok({ token, admin: token.user })
    } catch {
      return response.unauthorized('邮箱或密码错误')
    }
  }

  async logout({ auth, response }: HttpContext) {
    await auth.use('admin').revoke()
    return response.ok({ message: '管理员已退出登录' })
  }
}

4. 配置认证路由

在start/routes.ts中添加路由,并指定对应的守卫中间件:

import router from '@adonisjs/core/services/router'
const UserAuthController = () => import('#controllers/http/user_auth_controller')
const AdminAuthController = () => import('#controllers/http/admin_auth_controller')

// 用户认证路由
router.group(() => {
  router.post('/login', [UserAuthController, 'login'])
  router.post('/logout', [UserAuthController, 'logout']).use('auth:user')
}).prefix('/api/user/auth')

// 管理员认证路由
router.group(() => {
  router.post('/login', [AdminAuthController, 'login'])
  router.post('/logout', [AdminAuthController, 'logout']).use('auth:admin')
}).prefix('/api/admin/auth')

5. 验证多模型认证

现在你可以通过以下方式调用认证方法:

  • 用户登录:发送POST请求到/api/user/auth/login,传入email和password,成功后返回token
  • 管理员登录:发送POST请求到/api/admin/auth/login,传入email和password,成功后返回token
  • 在需要验证用户身份的路由中使用auth:user中间件,管理员则用auth:admin
  • 在控制器中通过auth.use('user').user获取当前登录用户,auth.use('admin').user获取当前登录管理员

内容的提问来源于stack exchange,提问作者Sakil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 20:19:51