如何在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-adminSDK,配置好Firebase服务账号。 - 根据Adonis.js版本(v5/v6)调整导入路径和类型定义,v6的Auth API略有差异。
- 可根据业务需求自定义错误处理逻辑,比如抛出特定异常而非直接返回响应。
内容的提问来源于stack exchange,提问作者Adam Galloway
相关产品推荐
相关产品推荐

