尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

GitHub CLI 多账户实战指南:gh v2.40.0 的 auth login / switch / logout 机制与源码解析

GitHub CLI 多账户实战指南:gh v2.40.0 的 auth login / switch / logout 机制与源码解析 GitHub CLI 多账户实战指南gh v2.40.0 的 auth login / switch / logout 机制与源码解析【免费下载链接】cliGitHub’s official command line tool项目地址: https://gitcode.com/GitHub_Trending/cli/cli本篇基于官方文档 multiple-accounts.md 讲解 GitHub CLIgh在 v2.40.0 引入的多账户支持auth login由覆盖式变为累加式新增gh auth switch命令切换主机上激活的账户auth token、auth switch、auth logout增加--user标志用于非交互场景下消歧。读完后你将掌握在同一台机器上安全地管理多个 GitHub 账户含 GitHub Enterprise的完整操作流并理解底层hosts.yml数据迁移、keyring 按用户存 token、以及auth refresh的跨账户防误用校验是如何在源码中实现的。背景从一个主机一个账户到多账户共存在 v2.40.0 之前gh强制维护每个主机对应一个账户的映射。这意味着针对同一个主机例如 github.com每次auth login都会替换掉之前用于 API 请求、以及当gh被配置为 git credential manager 时git 操作的 token。多账户需求在 GitHub 社区长期被反复提出社区也有过如gh-profile之类的第三方变通方案官方文档特别提及了这些社区贡献为这一特性铺平了道路。v2.40.0 的多账户支持同时覆盖 github.com 与 GitHub Enterprise。官方也明确这是 MVP刻意不实现基于上下文如pwd、git remote自动切换账户的场景但希望用户从此能用标准 OAuth 浏览器流程而非 PAT来获取并更新 token并安全地存储在gh管理的系统 keyring 中。本次版本的能力范围auth login 行为变为累加式多账户支持的核心是auth login从替换变为累加。以文档中的示例流程为例初始状态只有一个账户wilmartin_microsoftauth status报告它是激活账户➜ gh auth status github.com ✓ Logged in to github.com account wilmartin_microsoft (keyring) - Active account: true - Git operations protocol: https - Token: gho_************************************ - Token scopes: gist, read:org, repo, workflow以williammartin身份走浏览器 OAuth 流程执行auth login后auth status现在报告github.com下有两个账户且新账户成为激活账户➜ gh auth login ? What account do you want to log into? GitHub.com ? What is your preferred protocol for Git operations on this host? HTTPS ? How would you like to authenticate GitHub CLI? Login with a web browser ! First copy your one-time code: A1F4-3B3C Press Enter to open github.com in your browser... ✓ Authentication complete. - gh config set -h github.com git_protocol https ✓ Configured git protocol ✓ Logged in as williammartin ➜ gh auth status github.com ✓ Logged in to github.com account williammartin (keyring) - Active account: true - Git operations protocol: https - Token: gho_************************************ - Token scopes: gist, read:org, repo, workflow ✓ Logged in to github.com account wilmartin_microsoft (keyring) - Active account: false - Git operations protocol: https - Token: gho_************************************ - Token scopes: gist, read:org, repo, workflow激活的含义可以直接验证切换激活账户会切换gh发 API 请求所用的 token以及在gh配置为 git credential manager 时 git 操作所用的 token。用 API 验证当前激活 token 对应的用户➜ gh api /user | jq .login williammartin新增命令gh auth switchgh auth switch用于切换某个主机上的激活账户。它支持两个关键标志--hostname-h指定 GitHub 实例的主机名--user-u指定要切换到的账户。在 switch.go 中可以确认这两个标志的定义L63-L64命令帮助文档还写明了消歧规则若某主机恰好只有两个账户激活账户会自动切换不需要交互提示若账户超过两个则必须通过--user标志或交互提示消歧。这一自动切换逻辑在switchRun中有对应实现switch.go当候选集恰好为同一主机上的两个用户时代码会直接选中当前处于非激活状态的那个用户} else if len(candidates) 2 candidates[0].host candidates[1].host { // If there is a single host with two users, automatically switch to the // inactive user without prompting. ... }如果既不满足自动切换条件、又不是交互终端命令会报错要求显式指定--hostname与--userswitch.go这正是文档中强调的组合标志用于非交互消歧的原因。命令示例取自命令内置 Example 段# 通过交互提示选择主机和账户 $ gh auth switch # 将指定主机上的激活账户切换到指定用户 $ gh auth switch --hostname enterprise.internal --user monalisa实际运行效果➜ gh auth switch ✓ Switched active account for github.com to wilmartin_microsoft ➜ gh api /user | jq .login wilmartin_microsoft另外有一个值得注意的保护switchRun在切换前会调用shared.AuthTokenWriteable检查是否有GH_TOKEN之类的环境变量正在接管认证若有gh会提示当前环境变量值正在被用于认证并拒绝写入switch.go。auth token --user按用户取 tokengh auth token用于打印某主机某账户的认证 token多账户版本为其增加了--user标志。结合文档示例可以在自动化脚本中显式取指定账户的 token➜ GH_TOKEN$(gh auth token --user williammartin) gh api /user | jq .login williammartin从 token.go 的tokenRun可以看出取值路径的完整逻辑L64-L85--hostname缺省时取默认主机--user缺省时取该主机的激活账户tokenauthCfg.ActiveToken(hostname)指定--user时则按用户取 tokenauthCfg.TokenForUser(hostname, opts.Username)若设置了隐藏的--secure-storage标志则只从 keyring 中按用户读取TokenFromKeyringForUser。找不到 token 时会报no oauth token found for host account user。auth logout 的扩展登出即切换gh auth logout也被扩展了当主机上还有其余登录账户时登出目标账户后会自动切换到剩余账户多个候选时弹出选择提示。支持同样的--hostname/--user标志logout.go。➜ gh auth logout ? What account do you want to log out of? wilmartin_microsoft (github.com) ✓ Logged out of github.com account wilmartin_microsoft ✓ Switched active account for github.com to williammartin登出后自动切换的行为在 logout.go 中有清晰的实现登出前先记录ActiveUser(hostname)登出后再读一次如果激活用户发生了变化且新值非空就打印Switched active account for ...这行输出——这正是示例中第二行输出的来源。同样地登出前也会做AuthTokenWriteable检查环境变量接管认证时拒绝操作。需要明确的是与命令帮助文本一致auth logout只在本地删除存储的认证配置不会吊销 token要吊销所有gh生成的 token需要到 GitHub 的 applications 设置页选择 GitHub CLI 应用并 Revoke Access。本次版本明确不包含的能力文档列出了有意不纳入本版本的三项理解这些边界能避免错误预期基于上下文的自动切换例如根据pwd或git remote自动切换账户——官方选择留给社区方案切换时自动修改 git config如user.name、user.email不会随账户切换而更新用户级配置例如williammartin用vim而wilmartin_microsoft用emacs这种按账户区分的配置暂不支持。这些并非永久排除而是 MVP 取舍。已知边界与源码印证数据迁移hosts.yml 从一对一到一对多多账户改造最困难的部分是持久化数据旧版hosts.yml只支持主机到账户一对一的映射磁盘上已有数据的 schema 变更同时面临向前/向后兼容问题——对使用go-gh库的外部用户以及保证旧版gh在新配置下仍可用的场景。迁移逻辑在 internal/config/migration/multi_account.go 中注释完整描述了 schema 变化L31-L69# 迁移前host 级 user / oauth_token github.com: user: williammartin git_protocol: https # 迁移后新增 users 子树原有配置保留不动 github.com: user: williammartin git_protocol: https users: williammartin: oauth_token: xyz具体规则为每个主机创建新的users键以主机级user值作为条目若存在主机级oauth_token不安全存储将其复制到新用户条目下原主机级配置保留不动——这是为了保持对旧版gh和go-gh的向前兼容token 存储在 keyring 中时迁移会按用户重写 keyring 条目keyring 服务名为gh:hostname见keyringServiceNamemulti_account.go若配置中缺少用户名迁移会调用 GraphQLViewer.Login查询补全multi_account.go迁移版本由PreVersion()空因为本迁移正是引入 version 键与PostVersion()1标识L76-L84。任何命令运行都会触发该迁移尝试并在config.yml中新增version字段以辅助未来维护。迁移只执行一次如果你担心这些文件中的数据官方建议先备份——最坏情况下可以删除这些文件从头开始。向前兼容的例外--insecure-storage 组合存在一个已知场景下无法保持完整的双向兼容auth login --insecure-storage→ 升级到 v2.40.0执行迁移→ 在旧版本上再次auth login --insecure-storage→ 之后用auth switch使该账户激活。症状是可能使用了旧 token例如 scope 不同。原因是数据迁移只执行一次原始的 insecure token 被移动到auth switch后续会使用的位置旧版本再写入的 token 与之错位。不可变配置用户home-manager 等依赖 home-manager 等工具以不可变方式管理配置的用户在gh尝试向config.yml写入新的version字段时会遇到错误。这类用户需要更新 home-manager 配置脚本显式加入version: 1。auth refresh 的跨账户误用防护auth refresh允许为存储的 token 增加或减少 scope。多账户场景下它更容易产生意外刷新针对激活账户进行。给激活用户williammartin添加read:projectscope 并以其本人走浏览器流程是正常路径➜ gh auth refresh -s read:project ? What account do you want to refresh auth for? github.com ! First copy your one-time code: E79E-5FA2 Press Enter to open github.com in your browser... ✓ Authentication complete.但如果在为williammartin移除workflowscope 时浏览器里却用wilmartin_microsoft完成了流程会得到明确报错➜ gh auth refresh -r workflow ! First copy your one-time code: EEA3-091C Press Enter to open github.com in your browser... error refreshing credentials for williammartin, received credentials for wilmartin_microsoft, did you use the correct account in the browser?从源码看refreshRun先取出激活用户authCfg.ActiveUser(hostname)OAuth 流程返回后比较两者refresh.goactiveUser, _ : authCfg.ActiveUser(hostname) if activeUser ! username(activeUser) ! authedUser { return fmt.Errorf(error refreshing credentials for %s, received credentials for %s, did you use the correct account in the browser?, activeUser, authedUser) }刷新的工作方式是读取当前 token 的 scopes再请求一个按增减要求调整后的新 token见refreshRun中 L166-L201 的 scope 合并逻辑。如果以不同用户完成了浏览器流程就会拿到错误用户 意外 scope的 token。官方不认为refresh 的起止账户不一致是应支持的用例且存在误用风险因此在此报错。注意此时平台侧 token 实际上已经签发只是gh拒绝存储它。另外命令帮助文本中写明如果要刷新非激活账户的凭据需要先用gh auth switch切到该账户刷新完再切回refresh.go。GitHub Enterprise 上的账户选择页限制在 github.com 上若浏览器中登录了多个账户Device Flow 登录会展示一个中间页让你选择以哪个账户继续。但该中间页功能尚未进入 GHESGitHub Enterprise Server。因此在 GHES 上以多个账户登录时运行auth login之前要先确保浏览器中已认证为正确的用户。相关源码与测试索引内容路径多账户官方文档docs/multiple-accounts.mdgh auth switch实现含两账户自动切换逻辑pkg/cmd/auth/switch/switch.gogh auth switch测试pkg/cmd/auth/switch/switch_test.gogh auth token --user取值逻辑pkg/cmd/auth/token/token.gogh auth logout登出后自动切换逻辑pkg/cmd/auth/logout/logout.gogh auth refresh跨账户校验pkg/cmd/auth/refresh/refresh.gohosts.yml 多账户数据迁移internal/config/migration/multi_account.go迁移逻辑测试含 keyring 注入internal/config/migration/multi_account_test.go小结ghv2.40.0 起的多账户支持可以用三点概括auth login变为累加式登录、gh auth switch提供主机级激活账户切换两账户自动切换、多账户需--user/提示消歧、auth token/switch/logout统一支持--hostname--user组合标志以便脚本化。使用时需注意升级会一次性迁移hosts.yml并写入config.yml的version字段建议先备份配置home-manager 类不可变配置需手动加入version: 1--insecure-storage与跨版本操作存在已知兼容例外auth refresh只针对激活账户且会拒绝跨账户完成流程GHES 上多账户登录需预先在浏览器中选好身份。【免费下载链接】cliGitHub’s official command line tool项目地址: https://gitcode.com/GitHub_Trending/cli/cli创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表