
Logto Mock Social 连接器实战解析面向集成测试的模拟社交登录实现与版本演进【免费下载链接】logto Authentication and authorization infrastructure for SaaS and AI apps, built on OIDC and OAuth 2.1 with multi-tenancy, SSO, and RBAC.项目地址: https://gitcode.com/GitHub_Trending/lo/logtologto/connector-mock-social是 Logto 开源项目中专为集成测试设计的模拟社交登录连接器官方 README 明确标注 For integration tests only。本文以该包的 CHANGELOG 为骨架结合 源码实现、类型定义、集成测试用例 等仓库证据系统讲解其工作原理、配置方式、能力演进脉络以及在 Logto 集成测试体系中的实际用法帮助读者理解 Logto 社交连接器Social Connector的标准接口契约与测试驱动设计思路。连接器定位为什么需要模拟社交登录在 Logto 的架构中社交登录Social Sign-in通过连接器Connector接入第三方身份提供商如 Google、GitHub、微信等。真实连接器需要真实的 OAuth 授权端点、Client 凭证与用户账号无法在 CI 环境中稳定复现。为此Logto 在 packages/connectors/connector-mock-social 中实现了一个完全模拟的社交连接器授权地址指向一个约定的模拟域名http://mock-social/见 index.ts不需要真实的第三方服务即可完成重定向 → 回调 → 换取用户信息的完整社交登录链路被 packages/integration-tests 下大量 API 级与端到端测试复用用于验证社交登录、身份绑定、多身份管理等业务逻辑。从连接器元数据看它声明的id为mock-social-connector、target为mock-social、平台类型为ConnectorPlatform.Universal全平台通用并支持 Token 存储isTokenStorageSupported: true详细声明见 constant.ts。配置模型clientId 与 clientSecret该连接器的配置结构非常精简由 types.ts 中的mockSocialConfigGuard基于 zod定义export const mockSocialConfigGuard z.object({ clientId: z.string(), clientSecret: z.string(), });clientId模拟应用的客户端标识必填clientSecret模拟应用的客户端密钥必填。配套的配置模板 docs/config-template.json 给出了占位示例{ clientId: client-id, clientSecret: client-secret }在集成测试中实际写入的值被定义为常量见 connectors-mock.tsexport const mockSocialConnectorId mock-social-connector; export const mockSocialConnectorTarget mock-social; export const mockSocialConnectorConfig { clientId: client_id_value, clientSecret: client_secret_value, }; export const mockSocialConnectorNewConfig { clientId: client_id_value_new, clientSecret: client_secret_value_new, };mockSocialConnectorNewConfig用于测试更新连接器配置的场景。连接器通过configGuard在运行时对管理员下发的配置做校验不合法配置会在写入阶段即被拒绝——这是 Logto 所有连接器共用的配置校验机制。核心实现四个关键接口的源码级拆解createMockSocialConnectorindex.ts返回一个符合SocialConnector契约的对象包含metadata、type、configGuard以及三个核心方法。这些方法签名均来自 connector-kit 的社交连接器类型定义理解它们即可理解整个社交连接器抽象。1. getAuthorizationUri生成授权地址const getAuthorizationUri: GetAuthorizationUri async ( { state, redirectUri, connectorId, scope }, setSession ) { await setSession({ state, redirectUri, connectorId }); // ... const queryParams new URLSearchParams({ state, redirect_uri: redirectUri, scope: scope ?? defaultScope, }); return ${mockSocialAuthDomain}?${queryParams.toString()}; };调用setSession将state、redirectUri、connectorId写入连接器会话用于回调阶段校验生成http://mock-social/?state...redirect_uri...scope...形式的授权地址scope 处理优先使用调用方传入的scope未传入时回退到默认值defaultScope email profile源码中为硬编码常量。这正是 CHANGELOG 1.5.0 版本引入的能力详见下文能力演进章节。2. getUserInfo从回调数据解析用户信息const mockSocialDataGuard z.object({ code: z.string(), userId: z.optional(z.string()), email: z.string().optional(), phone: z.string().optional(), name: z.string().optional(), avatar: z.string().optional(), });回调数据要求必须包含code并支持可选的userId、email、phone、name、avatar。getUserInfo依次完成用mockSocialDataGuard校验回调数据校验失败抛出ConnectorError(ConnectorErrorCodes.InvalidResponse)调用validateConnectorSession确认连接器会话存在防 CSRF 的基础手段返回规范化用户信息其中用户 ID 优先取回调中的userId否则生成mock-social-sub-${randomUUID()}形式的随机 ID将原始回调数据原样放入rawData字段——这是 1.2.0 版本引入的返回并存储原始数据能力见下文。validateConnectorSession对NotImplemented错误做了宽容处理连接器会话能力未实现时忽略异常保证向后兼容。3. getTokenResponseAndUserInfoToken 存储模式下的组合取数const getTokenResponseAndUserInfo: GetTokenResponseAndUserInfo async (data, getSession) { const result mockSocialDataGuard .extend({ tokenResponse: tokenResponseGuard.optional() }) .safeParse(data); // ... return { userInfo: { id: userId ?? mock-social-sub-${randomUUID()}, ...rest, rawData: jsonGuard.parse(data) }, tokenResponse }; };当连接器启用 Token 存储元数据中isTokenStorageSupported: true时Logto 会调用该方法一次性获取 Token 响应与用户信息。它复用了mockSocialDataGuard并额外接受可选的tokenResponse字段结构由 connector-kit 的 tokenResponseGuard 定义支持id_token、access_token、refresh_token、expires_in、scope、token_type。SocialConnector类型还定义了可选的getAccessTokenByRefreshToken与validateSamlAssertionMock 连接器未实现它们——这类能力均为可选实现体现了连接器接口的渐进式设计。能力演进从 CHANGELOG 还原技术脉络该连接器的 CHANGELOG 记录了从 1.0.1 到 1.5.6 的全部版本。除去纯依赖升级Patch Changes共有 4 次带实质性变更的 Minor 版本逐条解析如下。1.5.0getAuthorizationUri 支持自定义 scopefeat: support custom scope in thegetAuthorizationUrimethod. This change allows thegetAuthorizationUrimethod in the social connectors to accept an extrascopeparameter, enabling more flexible authorization requests. If the scope is provided, it will be used in the authorization request; otherwise, the default scope configured in the connector settings will be used.对应 connector-kit 的类型定义中GetAuthorizationUri的 payload 增加了可选字段scope?: string。Mock 连接器的实现即上文所示scope: scope ?? defaultScope。需要说明的是按 CHANGELOG 描述未传 scope 时应使用连接器设置中的默认 scope而 Mock 连接器源码将其实现为硬编码常量email profile。这也符合其测试专用定位——真实连接器如 Google则会将scope作为可配置项写入configGuardconnector-kit 中 Google 连接器的配置即含scope: z.string().optional()。1.2.0返回并存储社交连接器原始数据return and store social connector raw data该变更对应getUserInfo/getTokenResponseAndUserInfo返回对象中的rawData字段通过jsonGuard.parse(data)序列化。SocialUserInfo类型见 social.ts定义了rawData?: Json使 Logto 能够在规范化的id/email/phone/name/avatar之外保留身份提供方返回的原始 JSON便于审计与排障。1.3.0切换 tsup 构建use tsup for building. Weve updated some of the packages to usetsupfor building. This will make the build process faster, and should not affect the functionality of the packages.这是 Logto monorepo 中一批包的工程化升级将构建工具统一为 tsup。从 package.json 可以看到该包目前的构建脚本为build: tsup、开发模式为dev: tsup --watch产物输出到lib/index.jsmain/module/exports均指向该文件包类型为 ESMtype: module。1.1.0 / 1.4.0Node 引擎版本要求1.1.0use Node 20 LTS for engine requirement同时将 TypeScript 升级至 5.3.3commit9089dbf84。CHANGELOG 特别注明由于 Logto 通过 Docker 镜像分发此项不构成用户侧破坏性变更1.4.0bump node version to ^22.14.0将 Node 版本要求提升至 22.14。当前 package.json 的engines字段为node: ^22.14.0与 1.4.0 的变更保持一致。1.3.1 的bump dependencies for security update则属于依赖安全更新。依赖演进与 connector-kit 的耦合关系该连接器是 connector-kit 最忠实的消费者之一两者几乎同步发版。将 CHANGELOG 中所有版本整理如下连接器版本变更类型connector-kit 版本实质变更1.5.6Patch5.1.1依赖升级1.5.5Patch5.1.0依赖升级1.5.4Patch5.0.1依赖升级1.5.3Patch5.0.0依赖升级1.5.2Patch4.7.0依赖升级1.5.1Patch4.6.0依赖升级1.5.0Minor4.4.0getAuthorizationUri支持自定义 scope1.4.0Minor4.3.0Node 版本升至 ^22.14.01.3.1Patch4.1.1依赖安全更新1.3.0Minor—改用 tsup 构建1.2.1Patch4.0.0依赖升级1.2.0Minor3.0.0返回并存储社交连接器原始数据1.1.0Minor2.1.0Node 20 LTS 引擎要求、TypeScript 5.3.31.0.1Patch2.0.0依赖升级可以看出getAuthorizationUri签名变更1.5.0与rawData能力1.2.0均需要 connector-kit 同步提供类型与 Guard 支持因此这两次 Minor 版本同时伴随着 connector-kit 的 Minor 升级4.4.0 与 3.0.0。源码层面index.ts 从logto/connector-kit导入的ConnectorError、ConnectorErrorCodes、ConnectorType、jsonGuard、tokenResponseGuard等正是这些接口契约的具体载体。实战用法集成测试中的完整链路Mock 连接器在 packages/integration-tests 中被系统化使用链路如下测试准备helpers/connector.ts 中的setSocialConnector()通过管理 API 创建连接器实例export const setSocialConnector async (api?: KyInstance) postConnector( { connectorId: mockSocialConnectorId, config: mockSocialConnectorConfig, syncProfile: true, }, api );场景覆盖mockSocialConnectorId被广泛引用在账户中心Account Center与体验 APIExperience API测试中例如 account/social.test.ts、account/social.delete-identity.test.ts、experience-api/interaction.test.ts 等覆盖社交登录、身份绑定linkSocialIdentity、身份替换、身份删除、仅社交登录标识符等场景。配置更新测试mockSocialConnectorNewConfig用于验证更新连接器配置后新配置生效如切换clientId这依赖configGuard对新旧配置的持续校验。此外包内还附带一个占位测试 src/index.test.ts仅it(makes ci happy)真正的行为验证交给集成测试层完成——这再次印证其仅服务于集成测试的定位。工程与发布细节从 package.json 可进一步了解该包工程化约定脚本checktsc 类型检查、build/devtsup 构建、testvitest、linteslint与prepublishOnly发布前自动构建依赖logto/connector-kitworkspace 协议、gotHTTP 客户端、snakecase-keys、zod校验发布文件lib、docs、logo.svg许可协议MPL-2.0。开发调试时可在仓库根目录执行pnpm --filter logto/connector-mock-social dev进入 tsup watch 模式pnpm --filter logto/connector-mock-social test运行包内测试。小结从 CHANGELOG 到源码logto/connector-mock-social展示了 Logto 连接器体系的两条核心设计原则契约先行连接器能力全部收敛在 connector-kit 的类型与 Guard 中GetAuthorizationUri、GetUserInfo、GetTokenResponseAndUserInfo等Mock 实现只需按契约填实现即可无缝接入 Logto 核心测试驱动用一个零依赖外部服务的模拟连接器把社交登录的完整链路授权地址生成、回调校验、用户信息解析、Token 存储搬进 CI从而在不依赖真实 OAuth 提供商的前提下保障业务逻辑的正确性。对于希望为 Logto 贡献新社交连接器或深入理解其抽象层的开发者从阅读该 Mock 连接器源码入手是性价比最高的起点它体量小、无外部依赖却完整覆盖了社交连接器的全部标准接口。【免费下载链接】logto Authentication and authorization infrastructure for SaaS and AI apps, built on OIDC and OAuth 2.1 with multi-tenancy, SSO, and RBAC.项目地址: https://gitcode.com/GitHub_Trending/lo/logto创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考