十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Backstage 接入 GitLab OAuth 认证:从 OAuth App 创建到登录解析器的完整配置指南

Backstage 接入 GitLab OAuth 认证:从 OAuth App 创建到登录解析器的完整配置指南 Backstage 接入 GitLab OAuth 认证从 OAuth App 创建到登录解析器的完整配置指南【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage导读本文基于 Backstage 开源仓库中的 GitLab 认证提供方Auth Provider文档完整讲解如何为开发者门户接入 GitLab OAuth 登录从在 GitLab 侧创建 OAuth Application、配置app-config.yaml到安装后端模块、在前端注册登录页并深入拆解内置 Sign-in Resolver 的匹配逻辑与源码实现。读完本文你将能够独立完成 GitLab 认证的端到端接入并掌握自托管 GitLab、自定义回调地址、会话时长等进阶配置的落地方式。GitLab Provider 概述Backstage 的core-plugin-api包自带一个基于GitLab OAuth的认证提供方可通过 GitLab 账号对用户进行认证。该提供方在仓库中由独立后端模块 backstage/plugin-auth-backend-module-gitlab-provider 实现前端侧则通过gitlabAuthApiRef暴露给插件使用。在 frontend-plugin-api 的 API 定义 中gitlabAuthApiRef被声明为同时具备OAuthApi、OpenIdConnectApi、ProfileInfoApi、BackstageIdentityApi与SessionApi能力的 Utility API这意味着它不仅可用于登录身份识别还可用于代表用户访问 GitLab 的第三方资源如创建 Merge Request、读取私有仓库等这正是 Backstage 认证体系 中双用途设计的体现。第一步在 GitLab 上创建 OAuth Application接入 GitLab 认证前必须先登录 GitLab 并在应用设置Application settings中创建一个 OAuth ApplicationApplication Name设置为backstage-dev或任何便于识别的名称。Redirect URIAuthorization Callback URL必须与 Backstage 中配置的 redirect URI 一致即指向 Backstage 后端的 auth handler本地开发http://localhost:7007/api/auth/gitlab/handler/frame非本地部署http://{APP_FQDN}:{APP_BACKEND_PORT}/api/auth/gitlab/handler/frame选择 Scopes按需勾选Scope权限说明使用场景apiAPI 的完整读写权限仅当用户需要用自身权限创建 Merge Request 时必需read_apiAPI 只读权限含所有组、项目、容器镜像仓库与包仓库读取 GitLab 数据read_user通过/userAPI 只读访问用户资料用户名、公开邮箱、全名并访问/users下的只读端点认证的最小必需项read_repository通过 Git-over-HTTP非 API只读访问私有项目仓库读取私有仓库write_repository通过 Git-over-HTTP非 API读写访问私有项目仓库写入私有仓库openid使用 OpenID Connect 认证 GitLab同时只读访问用户资料与组成员关系OIDC 认证profile使用 OpenID Connect 只读访问用户资料数据OIDC 认证email使用 OpenID Connect 只读访问用户主邮箱OIDC 认证需要特别说明的是read_user是源码层面强制要求的最小 Scope。authenticator.ts 中通过scopes: { required: [read_user] }声明了该提供方必需的 scope即使你在 GitLab 上只勾选了read_user认证流程也能正常完成。第二步在 app-config.yaml 中配置 Provider将以下配置加入根配置文件app-config.yaml的auth段auth: environment: development providers: gitlab: development: clientId: ${AUTH_GITLAB_CLIENT_ID} clientSecret: ${AUTH_GITLAB_CLIENT_SECRET} ## 自托管 GitLab 时取消注释 # audience: https://gitlab.company.com ## 使用自定义 redirect URI 时取消注释 # callbackUrl: https://${BASE_URL}/api/auth/gitlab/handler/frame ## 设置用户会话时长时取消注释 # sessionDuration: { hours: 24 } # 支持 ms 库格式如 24h、2 days、ISO 时长、代码中使用的人类可读时长 signIn: resolvers: # 更多 resolver 见下方 Resolvers 章节 - resolver: usernameMatchingUserEntityNameGitLab provider 的配置结构包含以下几个关键键其完整 schema 定义见 config.d.tsclientId在 GitLab 上生成的 Application ID例如4928c033ab3d592845c044a653bc20583baf84f2e67b954c6fdb32a532ab76c9。clientSecretApplication 对应的 Secret配置 schema 中标记为visibility secret不会被泄露到前端。audience可选自托管 GitLab 实例的基础 URL例如https://gitlab.company.com。留空时默认指向https://gitlab.com。callbackUrl可选与创建 OAuth App 时注册的 Redirect URI 匹配的 URL例如https://backstage.acme.corp/api/auth/gitlab/handler/frame。注意由于 GitLab OAuth 的一个特性URL 中frame之后不能带有尾部/。sessionDuration可选用户会话的存活时长。支持ms库格式如24h、2 days、ISO 8601 时长格式以及HumanDuration对象形式。additionalScopes可选需要追加到默认 scope 之外的额外 scope可配置为字符串或字符串数组见 config.d.ts。signIn.resolvers登录时用于将 GitLab 身份映射为 Backstage Catalog 用户实体的解析器列表见下文。audience 与 OAuth 端点源码揭示的底层行为在 authenticator.ts 中initialize阶段会读取配置并据此构造 OAuth 策略baseUrl取audience配置缺省为https://gitlab.com授权端点authorizationURL为${baseUrl}/oauth/authorize令牌端点tokenURL为${baseUrl}/oauth/token用户资料端点profileURL为${baseUrl}/api/v4/user。这意味着配置了audience: https://gitlab.company.com后整个 OAuth 流程会自动指向自托管实例的对应端点无需其他改动。同时start阶段会以accessType: offline、prompt: consent发起授权确保能拿到可用于刷新与离线调用的令牌。该行为在 module.test.ts 的集成测试中得到了验证测试启动后端后请求/api/auth/gitlab/start断言返回 302 重定向到https://gitlab.com/oauth/authorize且查询参数包含response_typecode、scoperead_user、client_id以及指向/api/auth/gitlab/handler/frame的redirect_uri并会写入名为gitlab-nonce的 nonce Cookie 用于防 CSRF。第三步后端安装 GitLab Provider 模块在 Backstage 根目录执行以下命令安装后端模块# from your Backstage root directory yarn --cwd packages/backend add backstage/plugin-auth-backend-module-gitlab-provider然后在packages/backend/src/index.ts中注册该模块配合backstage/plugin-auth-backendbackend.add(import(backstage/plugin-auth-backend)); /* highlight-add-start */ backend.add(import(backstage/plugin-auth-backend-module-gitlab-provider)); /* highlight-add-end */该模块在源码中定义为 authModuleGitlabProvider它是一个createBackendModulepluginId为auth、moduleId为gitlab-provider通过authProvidersExtensionPoint以providerId: gitlab注册 provider并使用createOAuthProviderFactory将gitlabAuthenticator与内置 Sign-in Resolver见下一节绑定。新后端系统New Backend System会据此自动挂载/api/auth/gitlab/*路由。第四步登录解析器Sign-in ResolversGitLab provider 开箱即用地提供了四种登录解析器用于将 GitLab 账号映射到 Catalog 中的 User 实体emailMatchingUserEntityProfileEmail用提供方返回的邮箱匹配spec.profile.email相同的 User 实体未匹配到时抛出NotFoundError。emailLocalPartMatchingUserEntityName用邮箱的本地部分之前的部分匹配name相同的 User 实体未匹配到时抛出NotFoundError。usernameMatchingUserEntityName用 GitLab 用户名匹配name相同的 User 实体未匹配到时抛出NotFoundError。userIdMatchingUserEntityAnnotation用 GitLab 用户 ID 匹配带有gitlab.com/user-id注解的 User 实体自托管 GitLab 为{integration-host}/user-id未匹配到时抛出NotFoundError。注意多个 resolver 会按顺序依次尝试但只有在抛出NotFoundError时才会跳过并尝试下一个其他错误会直接中断登录流程。解析器源码剖析gitlabSignInResolvers命名空间定义在 resolvers.ts其中usernameMatchingUserEntityName从result.fullProfile.username取出 GitLab 用户名若缺失则抛错随后调用ctx.signInWithCatalogUser({ entityRef: { name: id } })按实体名匹配。userIdMatchingUserEntityAnnotation从fullProfile.id取用户 ID并从fullProfile.profileUrl中解析出hostname即实例主机名例如gitlab.com或gitlab.company.com然后以注解${host}/user-id去匹配 User 实体。这正是文档中自托管实例使用{integration-host}/user-id一说的源码依据——注解键由资料页 URL 的主机名动态拼出。两种 resolver 都支持可选的dangerouslyAllowSignInWithoutUserInCatalog选项开启后即使 Catalog 中不存在对应 User 实体也会基于该标识符放行登录配合dangerousEntityRefFallback使用见 config.d.ts。如果这四种 resolver 不满足需求可以构建自定义 resolver详见 Sign-in Identities and Resolvers 文档的 Building Custom Resolvers 章节。第五步前端添加 GitLab 登录将 GitLab 添加到前端登录页需要引入gitlabAuthApiRef与SignInPage组件具体做法见 Adding the provider to the sign-in page。以新前端系统为例在packages/app/src/App.tsx中通过SignInPageBlueprint声明登录页import { createApp } from backstage/frontend-defaults; import { gitlabAuthApiRef } from backstage/core-plugin-api; import { SignInPageBlueprint } from backstage/plugin-app-react; import { SignInPage } from backstage/core-components; import { createFrontendModule } from backstage/frontend-plugin-api; const signInPage SignInPageBlueprint.make({ params: { loader: async () props ( SignInPage {...props} provider{{ id: gitlab-auth-provider, title: GitLab, message: Sign in using GitLab, apiRef: gitlabAuthApiRef, }} / ), }, }); export default createApp({ features: [ /* 其他插件与模块 */ createFrontendModule({ pluginId: app, extensions: [signInPage], }), ], });在 auth.ts 中gitlabAuthApiRef的 API id 为core.auth.gitlab并且core-plugin-api会将其重新导出见 core-plugin-api 的 auth 定义因此前端插件可以直接通过useApi(gitlabAuthApiRef)获取该认证 API既可用于登录也可用于获取访问令牌代表用户调用 GitLab API。进阶多环境与多登录方式按环境区分配置auth.providers.gitlab下的每个子键对应一个认证环境如development、productionBackstage 会根据本机auth.environment的设置选择对应的那组配置参见 认证总览文档 中的说明。多登录方式并存可通过SignInPage的providers数组同时提供 GitLab 与 guest 等多种登录方式并用configApi.getString(auth.environment)等配置信息条件渲染例如仅在开发环境开放 guest 登录。统一身份映射当使用多个登录方式时务必配置不同的 sign-in resolver使它们无论通过哪种方式登录都能解析到同一个用户身份。验证与测试仓库自带的集成测试 module.test.ts 展示了最小可运行配置只需在根配置中提供clientId与clientSecret可通过 mock 配置注入即可启动测试后端并验证请求/api/auth/gitlab/start?envdevelopment返回 302重定向目标为https://gitlab.com/oauth/authorize携带scoperead_user与正确的redirect_uri设置gitlab-nonceCookie并在state参数中编码env与nonce用于回调时的状态校验。这为自建部署后的连通性排查提供了很好的参照如果本地开发出现登录后跳回空白页或 302 重定向异常可对照该测试检查 redirect URI、scope 与环境名是否一致。常见问题与注意事项redirect URI 尾斜杠GitLab OAuth 对回调地址匹配较严格/api/auth/gitlab/handler/frame末尾不能加/GitLab 侧与callbackUrl配置需保持一致。自托管 GitLab务必设置audience为实例基础 URL如https://gitlab.company.com否则授权会默认指向https://gitlab.com见 authenticator.ts 的默认值逻辑。最小 scope后端强制要求read_userscope若登录失败提示 scope 缺失请检查 GitLab 侧勾选的权限列表。多环境冲突多个环境配置共存时auth.environment决定生效的那组clientId/clientSecret需确保与前端SignInPage的 provider id 对应。会话时长如需调整会话生命周期可通过sessionDuration配置如{ hours: 24 }、24h、2 days或 ISO 时长。【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表