对流-谷歌-天
A 类 对流组件 提供共享的
"轻松匿名/Google账户"身份计划被使用 upgallery 财务报告和审定财务报表
when: Google OIDC 登录服务器控件刷新令牌,加可选
匿名身份,由无记名无记名者索赔所支持
匿名证劫犯等级 结构固定,在一个地方.
安保模式
- 谷歌登录. Google发行ID代号; Convex 验证发行人,
并且通过应用程序签名
convex/auth.config.ts复习 符号从不离开组件authSessions表格 – 只有浏览器 持有不透明的 HMAC 签名的会话符号, 并交换它以换取新的 ID 通过刷新路径的符号。 每次刷新都会旋转会话符号 (有一个短的优雅窗口用于赛车标签),所以一个被过滤出的信使去 下个刷新时就停了 会议在180天后结束 默认闲置60天; 配置通过sessionAbsoluteTtlMs编号 :sessionIdleTtlMs打开new GooglyAuth(...)。签名使用prompt=select_account; 回调会以prompt=consent只有在需要刷新令牌且没有保存时. - 匿名用户(可选). 256位六分位数索赔确认 饼干 索赔是无记名秘密;只有SHA-256大麻被储存.
- 结构性劫机预防. 全权证书在自己的表格内
(单位:千美元)
googleCredentials, (中文(简体) ),anonymousCredentials)指向一个identities排队 将匿名账户升级到 Google 登录 删除 页:1 匿名证书行,所以退休的索赔不能保持第二, 密码无入帐——"标注兼有" 原图后的形状anonymousId劫持错误是 无法形容,一个防守的警卫退休 遗留下来的双重信用排 视之一见. 回归套件example/convex/auth.test.ts财务报告和审定财务报表src/component/lib.test.ts钉住所有这一切. - Apps从未见过证书. 组件将应用程序交给不透明
identityId字符串; 应用程序按它自己的配置表键 。 现场 升级不变identityId,所以当用户时应用程序数据不会移动 签入.
安装
npm install @clammet/convex-googly-auth
// convex/convex.config.ts
import { defineApp } from "convex/server";
import googlyAuth from "@clammet/convex-googly-auth/convex.config.js";
const app = defineApp();
app.use(googlyAuth);
export default app;
// convex/auth.config.ts
export default {
providers: [
{
domain: "https://accounts.google.com",
applicationID: process.env.AUTH_GOOGLE_ID,
},
],
};
部署时的环境变量: AUTH_GOOGLE_ID, (中文(简体) ),
AUTH_GOOGLE_SECRET, (中文(简体) ), SITE_URL (canonic web 起源).
服务器使用情况
// convex/lib/auth.ts — one instance for the whole app
import { GooglyAuth } from "@clammet/convex-googly-auth";
import { components } from "../_generated/api";
export const googly = new GooglyAuth(components.googlyAuth);
// Google-only app? Anonymous claims are then ignored server-side everywhere:
// export const googly = new GooglyAuth(components.googlyAuth, { anonymous: false });
// convex/profiles.ts — the app owns its profile table
export const ensureCurrent = mutation({
args: { anonymousClaim: v.optional(v.string()) },
handler: async (ctx, args) => {
const result = await googly.ensureIdentity(ctx, args);
// result.identityId — key your profile row by this (index it!)
// result.identity — the verified Google UserIdentity, or null
// result.upgraded — anonymous identity gained Google sign-in in place
// result.mergedFromId — an anonymous identity was absorbed into this
// one; move or alias your rows keyed by it
...
},
});
// In queries/mutations that need the caller:
const identityId = await googly.resolveIdentity(ctx, {
anonymousClaim: args.anonymousClaim,
});
// convex/http.ts
const http = httpRouter();
googly.registerRoutes(http, {
// All optional; defaults read AUTH_GOOGLE_ID / AUTH_GOOGLE_SECRET / SITE_URL.
allowedOrigins: ["https://alt.example.com"],
// Or check a table of custom domains:
// isAllowedOrigin: async (ctx, origin) => { ... },
});
export default http;
挂起的路由( 可通过 pathPrefix: GET /auth/google/start, (中文(简体) ),
GET /auth/google/callback, (中文(简体) ), POST /auth/refresh, (中文(简体) ), POST /auth/sign-out。 。 。 .
回调重定向到 {origin}/auth/callback 在网络应用.
可选地增加一个克龙呼叫 googly.cleanupExpiredSessions(ctx)。 。 。 .
反应使用
// src/lib/authClient.ts
import { createGooglyAuthClient } from "@clammet/convex-googly-auth/react";
export const authClient = createGooglyAuthClient({
convexSiteUrl: import.meta.env.VITE_CONVEX_SITE_URL,
googleClientId: import.meta.env.VITE_GOOGLE_CLIENT_ID,
storagePrefix: "myapp", // localStorage keys + claim cookie name
// anonymous: false, // must match the server-side option
});
// main.tsx
<authClient.GoogleAuthProvider>
<ConvexProviderWithAuth client={convex} useAuth={authClient.useConvexGooglyAuth}>
<App />
</ConvexProviderWithAuth>
</authClient.GoogleAuthProvider>
authClient.useGoogleAuth()→{ isLoading, isAuthenticated, signIn, signOut }authClient.useAnonymousClaim()- 要求转让给Convex职能 (仅限Google模式)- 在你身边
/auth/callback页面调用authClient.handleAuthCallback()一次 导航到返回的redirect(见example/src/App.tsx(中文(简体) ) - 签到后
ensure成功, 调用authClient.clearAnonymousClaim()
这个 example/ 目录是一个完整的工作应用程序; 运行测试
npm test消费者可以自己登记该组件 convex-test
套房通过 @clammet/convex-googly-auth/test (见
example/convex/setup.test.ts) (中文(简体) ).
移动升华 / 当移动到此组件时
两个应用程序都保留其配置表和授权逻辑;只有 证书列移入组件 .
- 添加
identityId: v.string()(已索引) 到配置表; 保留 只应用字段(播放名称,角色,时区,. - 后填: 对于每个配置行, 插入组件行 -
googleSubject− a 个googleCredentials排队,直播anonymousClaimHash编号 :anonymousId- 一个anonymousCredentials行数( 小时数)when简单的文字 编号为SHA-256 → 第 Base64url; 跳过任何匿名证书 具有 Google 主题的行 这些正是可以劫持的 。 。 。 将返回的身份编号存储于identityId。 。 。 . - 替换
getCurrentProfile- 有型号的助手googly.resolveIdentity(...)+a 键by_identityId剖面检索,以及 prototstrap/相生突变googly.ensureIdentity(...), (中文(简体) ), 处理mergedFromId与应用程序的现有合并策略 (上行:别名行;当:moveProfileData) (中文(简体) ). - 替换手卷
/auth/*HTTP 路线googly.registerRoutes(http, ...)(upgallery:通过一个isAllowedOrigin回调检查galleryHosts),前端则googleAuth.tsx索赔援助人员createGooglyAuthClient。 。 。 .
注释:
- 签名密钥来源于
AUTH_GOOGLE_SECRET加一个signingNamespace(默认)"googly-auth"因此,现有届会和 飞行中的 OAuth 状态在迁移时无效;用户只需签名即可 再来一次. when本地Storage UUID 软件anonymousIds为无效索赔(索赔为 (原始内容存档于2017-04-26). 64-hex. 要么接受移民前的匿名访客得到新鲜 身份,或做一次性的应用程序交换:服务器向上查找 将新的索偿(客户存储)附加到同一处 身份,然后删除遗留的 id.- 要求数
convex >= 1.43。 。 。 .
仓库布局
src/component/组成部分:计划(身份、证书、, (b) 安排会议工作。 拥有自己的_generated/。 。 。 .src/client/- 辅助GooglyAuth类和 HTTP 路由注册 (auth + env 访问发生在应用程序,而不是组件).src/react/——浏览器客户端工厂.src/test.ts—— 说convex-test注册助手(以@clammet/convex-googly-auth/test) (中文(简体) ).example/——工作示例app+回归测试套件.
发展
npm install --ignore-scripts # prepare runs a build; skip on first install
npm run build # or build:codegen with a configured deployment
npm run check