airi 前端鉴权指南:用 VueUse useAuth 在 Vue 3 中响应式绑定 Firebase Auth 登录状态
发布时间:2026/9/10 2:50:09来源:尧图网络
airi 前端鉴权指南用 VueUse useAuth 在 Vue 3 中响应式绑定 Firebase Auth 登录状态【免费下载链接】airi Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-samas altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airiuseAuth是 VueUse 官方 Firebase 集成vueuse/firebase提供的响应式鉴权绑定它把 Firebase Auth 的登录状态封装成user与isAuthenticated两个响应式值让 Vue 组件可以声明式地响应登录、登出与令牌刷新事件。本文以 airi 仓库中 vueuse-functions 技能库 的 useAuth 参考文档 为主体完整讲解其用法、返回值、底层监听机制与类型声明并结合 airi 仓库自研的响应式鉴权实现useAuthStore做源码级对照帮助你掌握用响应式状态驱动 UI 鉴权这一通用设计模式。一、技能定位useAuth 在 vueuse-functions 中的角色在 airi 仓库的.agents/skills/vueuse-functions/技能库中所有 VueUse 组合式函数按功能分类维护了各自的参考文档useAuth被归类在Firebase分组下与该分组的 useFirestore响应式 Firestore 绑定、useRTDB响应式 Realtime Database 绑定并列三者同属vueuse/firebase集成包。根据 SKILL.md 中的调用规则Invocation标注useAuth的调用级别为EXTERNAL即仅当用户已经安装了vueuse/firebase与firebase外部依赖时才应当使用否则需要先评估是否真正需要该依赖再决定是否安装。这是技能库对外部集成类组合式函数的通用约束——避免为了一句便利的响应式封装而引入整个 SDK。### Firebase | 函数 | 描述 | Invocation | |--------------|-----------------------------------|------------| | useAuth | Reactive Firebase Auth binding | EXTERNAL | | useFirestore | Reactive Firestore binding | EXTERNAL | | useRTDB | Reactive Firebase Realtime Database binding | EXTERNAL |从类型声明来看useAuth被标注了__NO_SIDE_EFFECTS__这是一个面向打包器的 tree-shaking 注解表示调用该函数本身不会产生模块级副作用从而允许构建工具在未使用该导入时安全地将其从产物中剔除。二、核心用法把 Firebase Auth 状态变成响应式数据useAuth的使用方式非常简洁它接收一个由 Firebase SDK 创建的Auth实例返回响应式的user与isAuthenticated。参考文档给出了一个可直接运行的最小示例Vue 3script setup语法script setup langts import { useAuth } from vueuse/firebase/useAuth import { initializeApp } from firebase/app import { getAuth, GoogleAuthProvider, signInWithPopup } from firebase/auth const app initializeApp({ /* config */ }) const auth getAuth(app) const { isAuthenticated, user } useAuth(auth) const signIn () signInWithPopup(auth, new GoogleAuthProvider()) /script template pre v-ifisAuthenticated{{ user }}/pre div v-else button clicksignIn Sign In with Google /button /div /template拆解这个示例可以得到完整的调用链初始化 Firebase 应用initializeApp({ /* config */ })需要传入你的 Firebase 项目配置apiKey、authDomain 等通常在应用入口处完成一次再通过模块导出复用获取 Auth 实例getAuth(app)从应用中取出认证实例它是后续所有鉴权操作的入口响应式绑定useAuth(auth)返回的isAuthenticated与user会随认证状态自动更新模板中无需手动刷新发起登录signInWithPopup(auth, new GoogleAuthProvider())是 Firebase 提供的弹出式 Google 登录方法——注意登录动作本身仍由 Firebase SDK 驱动useAuth只负责感知并传播状态变化。在真实业务中你通常还需要处理登出与用户信息展示。可以在同一组件中直接组合 Firebase 原生的signOut与useAuth的返回值形成完整的登录生命周期script setup langts import { useAuth } from vueuse/firebase/useAuth import { getAuth, signInWithPopup, signOut, GoogleAuthProvider } from firebase/auth const auth getAuth() const { isAuthenticated, user } useAuth(auth) const signIn () signInWithPopup(auth, new GoogleAuthProvider()) const signOutUser () signOut(auth) /script template div v-ifisAuthenticated user p{{ user.displayName ?? user.email }}/p button clicksignOutUserSign Out/button /div button v-else clicksignInSign In/button /templateuser是可空引用null表示未登录因此模板中与v-if组合使用时需要做空值守卫而isAuthenticated是布尔型计算属性可直接用于路由守卫、导航栏按钮、页面拦截等场景的条件分支。三、返回值详解参考文档用一张表明确了useAuth的两个返回值其类型与语义如下名称类型说明userRefUser \| null当前 Firebase 用户对象未认证时为nullisAuthenticatedComputedRefboolean当前是否处于已认证状态需要强调两个关键点user是RefisAuthenticated是ComputedRef。在script setup顶层解构后模板中可直接使用Vue 会自动解包在 JS 逻辑中则需通过.value访问或借助storeToRefs、toRefs等工具维持响应式。isAuthenticated是从user派生的即user.value ! null。这意味着它天然与user保持一致不存在user 已有值但 isAuthenticated 仍为 false的状态撕裂问题。四、底层原理onIdTokenChanged 监听器useAuth之所以能做到状态自动更新核心在于它内部注册了 Firebase Auth 的onIdTokenChanged监听器。参考文档明确指出The composable automatically updates when the users ID token changes (including sign-in, sign-out, and token refresh events) using FirebasesonIdTokenChangedlistener.onIdTokenChanged是 Firebase Auth 提供的状态监听 API它会在以下事件发生时触发回调登录sign-in包括signInWithPopup、signInWithRedirect、signInWithEmailAndPassword等所有登录方式完成之后登出sign-out调用signOut后用户对象变为nullID Token 刷新token refreshFirebase 会周期性地自动刷新用户的 ID Token默认约每小时此时也会触发监听——这正是useAuth相比只在登录/登出时手动更新一次的朴素实现更可靠的原因即使会话在后台被静默刷新响应式状态也始终与真实认证态同步。使用useAuth之后组件无需自己管理监听器的注册与解绑——这正是 VueUse 组合式函数依赖 Vue 组件作用域自动清理的设计惯例组件卸载时随 scope dispose 一并解除避免了传统onAuthStateChanged手动注册/卸载容易造成的内存泄漏问题。五、类型声明逐段解析参考文档给出了useAuth的完整 TypeScript 类型声明理解它能帮助你正确地消费user对象。整理后其签名结构为export declare function useAuth(auth: Auth): { isAuthenticated: ComputedRefboolean user: RefUser | null }其中User是对 Firebase 用户模型的静态类型描述包含以下关键字段与方法成员类型用途uidstring用户唯一标识跨会话稳定email/displayName/phoneNumber/photoURLstring \| null用户的邮箱、显示名、电话、头像链接可空emailVerifiedboolean邮箱是否已验证常用于未验证禁止访问策略isAnonymousboolean是否匿名用户匿名登录场景metadata{ creationTime?, lastSignInTime? }账号创建时间与最近登录时间providerData数组各登录提供方Google、GitHub 等对应的资料快照refreshTokenstring刷新令牌用于换取新的 ID TokentenantIdstring \| null多租户Firebase Identity Platform场景下的租户 IDdelete()() Promisevoid删除当前用户账号getIdToken(forceRefresh?)() Promisestring获取或强制刷新ID Token是携带 Bearer 请求头访问受保护 API 的常用方式getIdTokenResult(forceRefresh?)() PromiseIdTokenResult获取 ID Token 及其声明信息reload()() Promisevoid重新加载用户资料如邮箱验证后刷新状态toJSON()() object序列化为纯对象实际使用中最常消费的是uid、email、displayName、photoURL用于展示头像与昵称与getIdToken()用于向自己的后端接口传递凭证。六、源码级对照airi 仓库的响应式鉴权实现有趣的是airi 仓库本身并未使用 Firebase Auth而是采用了自研的OIDC Better Auth鉴权栈——但它在设计上与useAuth遵循着完全相同的响应式状态驱动 UI哲学。对照阅读可以加深你对本主题的理解。6.1 相同的响应式骨架user isAuthenticatedairi 的鉴权核心是 packages/stage-ui/src/stores/auth.ts 中的useAuthStorePinia store。它暴露了与useAuth同构的状态对const user refUser | null(null) const session refSession | null(null) const isAuthenticated computed(() !!user.value !!session.value)与 VueUseuseAuth一样user是RefisAuthenticated是派生的ComputedRef。只是 airi 的判定更严格——要求用户对象与服务端会话对象同时存在才视为已认证。6.2 监听状态迁移watch(isAuthenticated)useAuth通过onIdTokenChanged回调感知状态变化airi 则用 Vue 的watch监听isAuthenticated的翻转并在翻转时执行认证/登出钩子见 auth.ts#L369-L394watch(isAuthenticated, async (authenticated, wasAuthenticated) { if (authenticated) { void updateCredits() needsLogin.value false if (!wasAuthenticated) await dispatchHooks(authenticatedHooks, auth hook error) } else { credits.value 0 if (wasAuthenticated) await dispatchHooks(logoutHooks, logout hook error) } }, { immediate: true })这段实现展示了响应式鉴权的两个实用技巧{ immediate: true }store 初始化时立即执行一次保证注册钩子时若已登录则立刻触发对应 onAuthenticated 中的提前触发逻辑钩子机制用authenticatedHooks/logoutHooks数组注册回调业务模块通过onAuthenticated/onLogout订阅登录/登出事件解耦了状态变化与副作用执行。6.3 状态消费的 UI 侧印证在组件层airi 的鉴权按钮同样把状态解构成响应式变量供模板消费。以 controls-island-auth-button.vue 为例const { isAuthenticated, user, needsLogin, credits } storeToRefs(authStore)这与useAuth示例中解构出isAuthenticated和user在模板中v-if分支渲染的模式完全一致——响应式鉴权状态让 UI 的登录前/登录后切换变成纯粹的声明式渲染无需手动管理任何中间状态。6.4 更进一步的工程化401 自动刷新useAuth依赖 Firebase 自动刷新 ID Tokenairi 则在 packages/stage-ui/src/libs/auth-fetch.ts 的authedFetch中实现了401 → 单飞刷新令牌 → 重放请求的安全网机制。它之所以需要这层兜底正如代码注释所说明的时钟偏移、挂起的标签页、刷新后的竞态都可能让过期的 Bearer Token 泄漏出去auth-fetch.ts#L5-L19。这个思路同样适用于 Firebase 场景——即使onIdTokenChanged会传播刷新事件对后端请求仍建议在收到 401 时执行一次user.getIdToken(true)强制刷新后重试。七、典型应用场景与注意事项基于以上原理useAuth最常见的落地场景包括导航栏登录态切换v-ifisAuthenticated决定展示用户头像/登出还是登录按钮与 airi 中 HeaderAvatar.vue 的做法一致路由守卫与页面拦截在路由前置守卫中读取isAuthenticated.value未登录则重定向到登录页——airi 的 onboarding.vue 正是用watch([isAuthenticated, closeRequestId])实现登录引导的用户信息展示解构user后读取displayName、photoURL、email等字段渲染头像与昵称受保护 API 调用用user.getIdToken()获取 ID Token 作为 Bearer 凭证请求后端。使用时的注意事项user为null时访问其属性会报错模板中务必用v-if/v-else分流或可选链user?.displayNameisAuthenticated是计算属性不要直接对它赋值需要手动重置状态时应通过signOut完成useAuth要求前置安装firebase与vueuse/firebaseEXTERNAL 调用级别若项目尚未使用 Firebase请先评估是否值得为响应式封装引入整套 SDK当页面同时存在多个组件调用useAuth时它们共享同一个Auth实例的监听结果状态保持一致不会出现互相覆盖的问题。结语useAuth以极小的 API 面一个函数、两个返回值解决了 Firebase 前端鉴权中最常见的痛点——登录状态的响应式同步。它的设计精髓在于把监听外部异步状态这一样板逻辑封装进组合式函数让组件只关心状态是什么而不用关心状态怎么来的。airi 仓库自研的useAuthStore虽然在技术上选择了 OIDC Better Auth 而非 Firebase但其user/isAuthenticated/watch(isAuthenticated)的结构与useAuth如出一辙印证了这一模式在真实项目中的可迁移性。掌握useAuth也就掌握了在任意 Vue 3 项目中搭建响应式鉴权层的通用范式。参考文档.agents/skills/vueuse-functions/references/useAuth.md 技能索引.agents/skills/vueuse-functions/SKILL.md airi 对照实现packages/stage-ui/src/stores/auth.ts【免费下载链接】airi Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-samas altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网