ブログ一覧に戻る
NestJSバックエンドTypeScript

NestJS × Firebase Auth で認証基盤を構築する

はじめに

NestJS と Firebase Auth を組み合わせることで、スケーラブルで安全な認証基盤を素早く構築できます。本記事では、カスタム Guard の実装からロールベースアクセス制御まで、実装手順を解説します。

Firebase Admin SDK のセットアップ

まず、Firebase Admin SDK を NestJS に組み込むためのモジュールを作成します。

// firebase-admin.module.ts
@Module({
  providers: [
    {
      provide: "FIREBASE_ADMIN",
      useFactory: () => {
        return admin.initializeApp({
          credential: admin.credential.applicationDefault(),
        });
      },
    },
  ],
  exports: ["FIREBASE_ADMIN"],
})
export class FirebaseAdminModule {}

AuthGuard の実装

Firebase ID トークンを検証する Guard を作成します。

@Injectable()
export class FirebaseAuthGuard implements CanActivate {
  constructor(@Inject("FIREBASE_ADMIN") private firebaseApp: admin.app.App) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest();
    const authHeader = request.headers.authorization;

    if (!authHeader?.startsWith("Bearer ")) {
      throw new UnauthorizedException();
    }

    const token = authHeader.split("Bearer ")[1];
    const decoded = await this.firebaseApp.auth().verifyIdToken(token);

    request.user = decoded;
    return true;
  }
}

ロールベースアクセス制御

カスタムデコレータと Guard を組み合わせて、ロールベースのアクセス制御を実現します。

// roles.decorator.ts
export const Roles = (...roles: string[]) => SetMetadata("roles", roles);

// roles.guard.ts
@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const roles = this.reflector.get<string[]>("roles", context.getHandler());
    if (!roles) return true;

    const request = context.switchToHttp().getRequest();
    const userRole = request.user?.role;
    return roles.includes(userRole);
  }
}

コントローラーでの使用

@Controller("admin")
@UseGuards(FirebaseAuthGuard, RolesGuard)
export class AdminController {
  @Get("users")
  @Roles("admin")
  findAllUsers() {
    return this.userService.findAll();
  }
}

まとめ

NestJS の DI と Guard の仕組みは、Firebase Auth との相性が非常に良いです。この構成をベースに、マルチテナントや権限管理など、より複雑な要件にも対応できます。