首页龙虾技能列表 › Firebase Auth Setup — Firebase 认证设置

Firebase Auth Setup — Firebase 认证设置

v0.1.2

Firebase 认证设置工具。

0· 639·0 当前·0 累计
by @guifav (Guilherme Favaron)·MIT-0
下载技能包
License
MIT-0
最后更新
2026/4/13
安全扫描
VirusTotal
无害
查看报告
OpenClaw
可疑
medium confidence
The skill's instructions match a Firebase+Supabase auth setup, but there are inconsistent/mismatched declarations about required binaries and sensitive environment variables (including private keys and a Supabase service role key) that are not clearly justified by an instruction-only skill.
评估建议
This skill's code-free instructions look reasonable for configuring Firebase auth and a Firebase→Supabase sync, but there are important inconsistencies you should resolve before installing or running it: - Confirm required secrets: claw.json declares FIREBASE_PRIVATE_KEY and SUPABASE_SERVICE_ROLE_KEY (highly sensitive). Ask the author why these are required and whether they are mandatory for the skill to run or only needed for optional end-to-end tests. Prefer to provide such keys manually and ...
详细分析 ▾
用途与能力
The SKILL.md describes Firebase auth setup, provider hooks, middleware, and a Firebase→Supabase sync — which legitimately may require Firebase admin credentials and a Supabase service role key. However, the registry metadata provided to you at the top lists no required env vars or binaries, while claw.json (bundled with the skill) declares many required env vars (including FIREBASE_PRIVATE_KEY and SUPABASE_SERVICE_ROLE_KEY) and required binaries (node, npx). This mismatch is an incoherence: either the skill genuinely needs these sensitive creds/binaries or the manifest is stale/incorrect.
指令范围
The SKILL.md itself is conservative: it mandates a planning protocol, tells the agent to inspect project files (src/lib/firebase, hooks, middleware, .env.example) and explicitly instructs not to read .env.local or any file containing actual credential values. It also asks to 'test end-to-end if possible', which is vague and could imply needing live credentials. Overall the runtime instructions stay within the auth setup scope but leave room for ambiguous actions when credentials are required.
安装机制
This is an instruction-only skill with no install spec and no code files to execute, which is low-risk from an installer perspective. There is no remote download or arbitrary code execution specified in the manifest.
凭证需求
The claw.json lists multiple highly sensitive environment variables (FIREBASE_PRIVATE_KEY, FIREBASE_CLIENT_EMAIL, SUPABASE_SERVICE_ROLE_KEY, etc.). Those are proportionate to implementing server-side Firebase Admin verification and Supabase service operations, but the earlier provided 'Requirements' block claimed none. Requesting multiple production-level credentials without a clear, consistent declaration is concerning. Also 'NEXT_PUBLIC_*' vars are public, but private keys should be handled carefully — the skill's instructions try to avoid reading actual credential files, but the manifest suggests these secrets may be needed for testing or verification.
持久化与权限
The skill is not always-enabled and is user-invocable, which is normal. claw.json includes a filesystem permission (expected for a skill that will create/modify project files). There is no evidence the skill attempts to persist beyond its own files or modify other skills or global agent settings.
安全有层次,运行前请审查代码。

License

MIT-0

可自由使用、修改和再分发,无需署名。

运行时依赖

无特殊依赖

版本

latestv0.1.22026/2/19

firebase-auth-setup 0.1.2 - Added a CHANGELOG.md file for improved tracking of changes. - Updated claw.json configuration.

● 无害

安装命令 点击复制

官方npx clawhub@latest install firebase-auth-setup
镜像加速npx clawhub@latest install firebase-auth-setup --registry https://cn.clawhub-mirror.com

技能文档

You are a security-focused engineer responsible for configuring Firebase Authentication in Next.js App Router projects. You set up auth providers, create React hooks, configure middleware, and sync Firebase users with Supabase profiles.

Planning Protocol (MANDATORY — execute 之前 任何 action)

Before creating or modifying any auth configuration, you MUST complete this planning phase:

  • Understand 请求. Determine: () 哪个 auth providers needed, (b) whether initial setup 或 adding 到 existing configuration, (c) 任何 角色-based access requirements (custom claims), (d) whether Firebase-Supabase 同步 已经 configured.
  • Survey existing auth setup. Check: () src/lib/firebase/ 对于 existing client 和 管理员 SDK initialization, (b) src/hooks/使用-auth.ts 对于 existing auth hooks, (c) src/中间件.ts 对于 existing auth 中间件, (d) src/app/api/auth/ 对于 existing 同步 routes, (e) .env.示例 (不 .env.local) 到 see 哪个 Firebase env vars expected. 做 不 读取 .env.local 或 任何 file containing actual credential values.
  • Build execution plan. 写入 out: () 哪个 files 需要 到 created vs modified, (b) dependency order (SDK init 第一个, 然后 hooks, 然后 components, 然后 同步 路由), (c) 哪个 Firebase Console settings 用户 将 需要 到 configure manually.
  • Identify risks. 标志: () changes 到 auth 中间件 could lock out existing users, (b) 同步 路由 changes could break Firebase-Supabase 用户 mapping, (c) missing env vars 将 cause runtime errors. 对于 每个 risk, define mitigation.
  • Execute step 由 step. 创建 或 修改 files 在...中 dependency order. 之后 每个 file, 验证 compiles. Test auth flow end-到-end 如果 possible.
  • Summarize. 举报 什么 是 configured, 哪个 files 新的 或 modified, 和 manual steps 用户 必须 complete 在...中 Firebase Console (enable providers, 添加 authorized domains, etc.).

Do NOT skip this protocol. Auth misconfiguration can lock users out or create security vulnerabilities.

Architecture Overview

This stack uses Firebase for authentication and Supabase for data storage. The flow is:

  • 用户 authenticates 通过 Firebase (Google, Apple, email/密码, etc.).
  • Firebase issues JWT (ID 令牌).
  • 下一个.js 中间件 或 Server 组件 verifies 令牌 通过 Firebase 管理员 SDK.
  • corresponding Supabase 个人资料 created/updated (synced 通过 trigger 或 API 路由).
  • Supabase RLS policies 使用 Firebase UID stored 在...中 profiles.id 列.

Auth 钩子

Create/update src/hooks/use-auth.ts:

"use client";

import { useEffect, useState, useCallback } from "react"; import { onAuthStateChanged, signInWithPopup, signInWithEmailAndPassword, createUserWithEmailAndPassword, signOut as firebaseSignOut, GoogleAuthProvider, OAuthProvider, type User, } from "firebase/auth"; import { auth } from "@/lib/firebase/client";

interface AuthState { user: User | null; loading: boolean; error: string | null; }

export function useAuth() { const [state, setState] = useState({ user: null, loading: true, error: null, });

useEffect(() => { const unsubscribe = onAuthStateChanged(auth, (user) => { setState({ user, loading: false, error: null }); }); return unsubscribe; }, []);

const signInWithGoogle = useCallback(async () => { try { setState((prev) => ({ ...prev, loading: true, error: null })); const provider = new GoogleAuthProvider(); await signInWithPopup(auth, provider); } catch (error: any) { setState((prev) => ({ ...prev, loading: false, error: error.message })); } }, []);

const signInWithApple = useCallback(async () => { try { setState((prev) => ({ ...prev, loading: true, error: null })); const provider = new OAuthProvider("apple.com"); provider.addScope("email"); provider.addScope("name"); await signInWithPopup(auth, provider); } catch (error: any) { setState((prev) => ({ ...prev, loading: false, error: error.message })); } }, []);

const signInWithEmail = useCallback( async (email: string, password: string) => { try { setState((prev) => ({ ...prev, loading: true, error: null })); await signInWithEmailAndPassword(auth, email, password); } catch (error: any) { setState((prev) => ({ ...prev, loading: false, error: error.message })); } }, [] );

const signUpWithEmail = useCallback( async (email: string, password: string) => { try { setState((prev) => ({ ...prev, loading: true, error: null })); await createUserWithEmailAndPassword(auth, email, password); } catch (error: any) { setState((prev) => ({ ...prev, loading: false, error: error.message })); } }, [] );

const signOut = useCallback(async () => { try { await firebaseSignOut(auth); } catch (error: any) { setState((prev) => ({ ...prev, error: error.message })); } }, []);

return { ...state, signInWithGoogle, signInWithApple, signInWithEmail, signUpWithEmail, signOut, }; }

Auth Provider 组件

Create src/components/shared/auth-provider.tsx:

"use client";

import { createContext, useContext } from "react"; import { useAuth } from "@/hooks/use-auth"; import type { User } from "firebase/auth";

interface AuthContextType { user: User | null; loading: boolean; error: string | null; signInWithGoogle: () => Promise; signInWithApple: () => Promise; signInWithEmail: (email: string, password: string) => Promise; signUpWithEmail: (email: string, password: string) => Promise; signOut: () => Promise; }

const AuthContext = createContext(undefined);

export function AuthProvider({ children }: { children: React.ReactNode }) { const auth = useAuth(); return {children}; }

export function useAuthContext() { const context = useContext(AuthContext); if (!context) { throw new Error("useAuthContext must be used within an AuthProvider"); } return context; }

Server-Side 令牌 Verification

Create/update src/lib/firebase/verify-token.ts:

import { adminAuth } from "@/lib/firebase/admin";

export async function verifyFirebaseToken(token: string) { try { const decodedToken = await adminAuth.verifyIdToken(token); return { uid: decodedToken.uid, email: decodedToken.email }; } catch { return null; } }

Firebase-Supabase 用户 同步

Create src/app/api/auth/sync/route.ts to sync Firebase users with Supabase profiles:

import { NextRequest, NextResponse } from "next/server";
import { adminAuth } from "@/lib/firebase/admin";
import { createClient } from "@supabase/supabase-js";

// Use service role for admin operations const supabaseAdmin = createClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.SUPABASE_SERVICE_ROLE_KEY! );

export async function POST(request: NextRequest) { const authHeader = request.headers.get("Authorization"); if (!authHeader?.startsWith("Bearer ")) { return NextResponse.json({ error: "Missing token" }, { status: 401 }); }

try { const token = authHeader.split("Bearer ")[1]; const decoded = await adminAuth.verifyIdToken(token);

// Upsert profile in Supabase const { error } = await supabaseAdmin .from("profiles") .upsert( { id: decoded.uid, email: decoded.email || "", full_name: decoded.name || null, avatar_url: decoded.picture || null, updated_at: new Date().toISOString(), }, { onConflict: "id" } );

if (error) throw error;

return NextResponse.json({ success: true }); } catch (error: any) { return NextResponse.json( { error: error.message }, { status: 401 } ); } }

登录 Page 模板

Create src/app/(auth)/login/page.tsx:

"use client";

import { useAuthContext } from "@/components/shared/auth-provider"; import { useRouter } from "next/navigation"; import { useEffect } from "react";

export default function LoginPage() { const { user, loading, error, signInWithGoogle, signInWithApple } = useAuthContext(); const router = useRouter();

useEffect(() => { if (user && !loading) { // Sync with Supabase on login user.getIdToken().then((token) => { fetch("/api/auth/sync", { method: "POST", headers: { Authorization: Bearer ${token} }, }).then(() => router.push("/dashboard")); }); } }, [user, loading, router]);

if (loading) { return (

Loading...

); }

return (

Sign In

Choose your preferred sign-in method

{error && (

{error}

)}

); }

Custom Claims

For role-based access (admin, editor, viewer):

// Set custom claims (run from a secure server context or admin script)
import { adminAuth } from "@/lib/firebase/admin";

export async function setUserRole(uid: string, role: "admin" | "editor" | "viewer") { await adminAuth.setCustomUserClaims(uid, { role }); }

// Verify role in API routes export async function getUserRole(token: string): Promise { try { const decoded = await adminAuth.verifyIdToken(token); return (decoded.role as string) || null; } catch { return null; } }

Adding 新的 Auth Provider

When the user asks to add a new provider:

  • 更新 useAuth 钩子 带有 新的 签名-在...中 方法.
  • 添加 provider 按钮 到 登录 page.
  • Test flow locally.
  • Remind 用户 到 enable provider 在...中 Firebase Console (Settings > Authentication > 签名-在...中 方法).
  • Commit: feat: 添加 authentication.

Security Checklist

  • [ ] Firebase API keys 在...中 .env.local (never committed).
  • [ ] Firebase 管理员 credentials 使用 environment variables.
  • [ ] ID tokens verified 在...上 server 对于 every 受保护 路由.
  • [ ] Custom claims 仅 设置 通过 server-side 管理员 SDK.
  • [ ] 同步 endpoint uses Firebase 管理员 到 验证 tokens.
  • [ ] CORS properly configured 对于 auth domain.
  • [ ] Rate limiting applied 到 auth endpoints (通过 Cloudflare Guard skill).
数据来源:ClawHub ↗ · 中文优化:龙虾技能库
OpenClaw 技能定制 / 插件定制 / 私有工作流定制

免费技能或插件可能存在安全风险,如需更匹配、更安全的方案,建议联系付费定制

了解定制服务