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

如何在Adonis.js中实现Firebase自定义认证守卫?

实现Adonis.js自定义Firebase Token认证Guard

1. 创建自定义Guard类

在app/Auth/Guards目录下创建FirebaseTokenGuard.ts(若用JavaScript则创建.js文件),继承Adonis.js的BaseGuard并实现核心认证逻辑:

import { BaseGuard } from '@adonisjs/auth/build/standalone'
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import admin from 'firebase-admin'
import User from 'App/Models/User'

export default class FirebaseTokenGuard extends BaseGuard {
  constructor(
    protected ctx: HttpContextContract,
    protected provider: any
  ) {
    super(ctx, provider)
  }

  /**
   * 核心认证:解析验证Firebase Token,通过手机号查找用户
   */
  public async authenticate() {
    const authHeader = this.ctx.request.header('Authorization')
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
      this.ctx.response.unauthorized('缺失或无效的Firebase Token')
      return null
    }

    const firebaseToken = authHeader.split(' ')[1]

    try {
      // 验证解码Firebase Token
      const decodedToken = await admin.auth().verifyIdToken(firebaseToken)
      const phoneNumber = decodedToken.phoneNumber

      if (!phoneNumber) {
        this.ctx.response.unauthorized('Firebase Token未包含手机号')
        return null
      }

      // 通过手机号查询用户
      const user = await User.query().where('phone_number', phoneNumber).first()
      if (!user) {
        this.ctx.response.unauthorized('该手机号未关联用户')
        return null
      }

      this.user = user
      return user
    } catch (error) {
      this.ctx.response.unauthorized('无效的Firebase Token')
      return null
    }
  }

  /**
   * 检查用户是否已认证
   */
  public async check() {
    const user = await this.authenticate()
    return !!user
  }

  /**
   * 注销逻辑(Firebase Token无状态,直接返回true)
   */
  public async logout() {
    return true
  }
}

2. 注册自定义Guard

在start/kernel.ts中注册你的Guard:

import FirebaseTokenGuard from 'App/Auth/Guards/FirebaseTokenGuard'
import Auth from '@ioc:Adonis/Addons/Auth'

Auth.extend('guard', 'firebase-token', () => {
  return new FirebaseTokenGuard(/* 上下文和用户提供者由Adonis自动注入 */)
})

3. 配置Auth守卫

修改config/auth.ts,新增Firebase Token守卫配置:

export const authConfig: AuthConfig = {
  guard: 'web',
  guards: {
    // 原有邮箱密码Token守卫
    api: {
      driver: 'oat',
      tokenProvider: {
        type: 'api',
        driver: 'database',
        table: 'api_tokens',
        foreignKey: 'user_id',
      },
      provider: {
        driver: 'lucid',
        identifierKey: 'id',
        uids: ['email'],
        model: () => import('App/Models/User'),
      },
    },
    // 新增Firebase Token守卫
    firebase: {
      driver: 'firebase-token', // 对应注册的守卫名称
      provider: {
        driver: 'lucid',
        identifierKey: 'id',
        model: () => import('App/Models/User'),
      },
    },
  },
}

4. 使用自定义Guard

在路由或控制器中调用该守卫完成认证:

// 路由示例
Route.get('/protected', async ({ auth }) => {
  const user = await auth.use('firebase').authenticate()
  return { user: user.serialize() }
}).middleware('auth:firebase')

// 控制器示例
export default class ProtectedController {
  public async index({ auth }) {
    await auth.use('firebase').check()
    const user = auth.use('firebase').user
    return { user }
  }
}

注意事项

  • 确保已安装并初始化firebase-admin SDK,配置好Firebase服务账号。
  • 根据Adonis.js版本(v5/v6)调整导入路径和类型定义,v6的Auth API略有差异。
  • 可根据业务需求自定义错误处理逻辑,比如抛出特定异常而非直接返回响应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 00:56:04