ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Git 账号切换全攻略:彻底解决 403 权限错误(HTTPS + SSH)

Git 账号切换全攻略:彻底解决 403 权限错误(HTTPS + SSH) 刚接触 Git 的人十有八九在换电脑、换公司、或者被拉进新项目组的时候遇到过这么一幕代码写好了git push结果红屏——remote: Permission to xxx/xxx.git denied to old_user紧跟着一句fatal: unable to access ... The requested URL returned error: 403。这时候很多人的第一反应是改配置git config --global user.name 新用户名改完再 push还是 403。然后就开始怀疑人生甚至怀疑是不是被服务器拉黑了。其实 403 这个报错绝大多数情况不是服务器封了你而是 Git 客户端还在偷偷用上一个账号的“登录状态”去访问远端。也就是说你光改了名字没用得让 Git 真正“换人”。这篇就把切换 Git 登录账号这件事彻底讲透覆盖 HTTPS 和 SSH 两种主流方式也顺带把多账号并存、令牌过期这类衍生问题一并解决。适合三类人看刚被 403 折磨的新手、被调去维护其他账号的同事、同一台电脑需要管公司私有仓库和个人开源仓库的老手。1. 先搞清楚403 到底是谁在拦你1.1 403 不是一种病三种情况都长一个样Git 报 403看起来都是“没权限”但背后的成因完全不一样。先学会看报错误文能省掉一半排查时间。最常见的三种remote: Permission to org/repo.git denied to old_user.—— 这是认证已经通过了但服务器觉得当前这个账号old_user没有操作该仓库的权限。可能是被移出了团队、仓库改成了私有、或者你确实在用另一个人的账号在访问。fatal: unable to access https://github.com/xxx/xxx.git/: The requested URL returned error: 403—— 这种是凭据本身有问题比如令牌过期、被吊销、密码错误或者网络中间层拦截了请求。remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.—— 这是 GitHub 在明确告诉你别再拿账号密码推送了用 Personal Access Token个人访问令牌。区分技巧报错里带着denied to 某账号名那就是账号权限问题先去仓库后台加人报错里只有一段 URL 和 403先怀疑令牌和凭据报错里直接提到 token / password authentication就老老实实去换成令牌。1.2 最容易闹的笑话改了 user.name 还是 403很多人包括当年的我第一个动作就是改user.name和user.email以为这就是“切换账号”。但这两个配置压根不负责认证。user.name和user.email干的事只是写到每次 commit 的元数据里告诉别人“这次提交是谁做的”。它们影响的是提交记录的作者信息和“你有没有权限往远端推代码”完全是两码事。你可以做个实验把user.name改成任何名字甚至改成钢铁侠只要git push时远端认证没变服务器照样按旧账号判断你的权限。所以改完还 403 是非常正常的不是配置没生效而是你改错了地方。那什么时候需要改user.name和user.email答案是当提交记录里挂错了人或者团队要求提交作者必须匹配公司邮箱时。它管的是“面子”不是“身份”。1.3 你走的是哪扇门HTTPS 还是 SSHGit 访问远端仓库有两种主流通道切换账号的方法完全不同。先跑一句命令看看你用的是哪条路git remote -v如果输出是https://github.com/xxx/xxx.git—— 走的是 HTTPS认证靠“凭据管理器 令牌/密码”。如果输出是gitgithub.com:xxx/xxx.git—— 走的是 SSH认证靠“本机私钥 远端公钥”。HTTPS 切换账号核心是让 Git 忘掉老的凭据重新输入新身份SSH 切换账号核心是换一对密钥或者让 Git 知道用哪把私钥去连哪个主机。记住不要拿 SSH 的钥匙去开 HTTPS 的门反之亦然。先确认通道再对症下药。2. HTTPS 场景切换账号的正规姿势2.1 先确认当前被记住的账号是谁HTTPS 方式下Git 会把你的登录状态存到系统的“凭据管理器”里下次访问同一主机时自动带上。所以第一步是先看它存了什么。git config --global --list git config --global credential.helpercredential.helper的值能告诉你凭据存在哪manager或manager-coreWindows 凭据管理器osxkeychainmacOS 钥匙串普通文件路径存在~/.git-credentials明文文件里再配合git remote -v看重定向到了哪台主机比如https://github.com/。知道了“存哪了 是哪个主机”就可以精准删除对应条目。2.2 不同系统“忘记”老账号的方法Windows最常踩坑老版本 Git 用manager新版本用manager-core但不管哪个最终都落在 Windows 凭据管理器里。清理步骤打开控制面板 → 用户账户 → 凭据管理器 → Windows 凭据。在列表里找到git:https://github.com或git:https://gitlab.com这样的条目。点开选择“删除”。也可以一步到位用命令行删cmdkey /delete:git:https://github.com删完再去git pushGit 会重新弹出登录窗口这时候输入新账号的令牌或密码即可。macOS凭据在钥匙串里。可以直接打开“钥匙串访问”搜索github.com找到git:https://github.com条目删除。更稳的方式是用命令行git credential-osxkeychain erase hostgithub.com protocolhttps输入完按两次回车提交就能清掉该主机的凭据。Linux如果配置了 file 类型的 helper凭据明文存在~/.git-credentials直接编辑删除对应行即可vim ~/.git-credentials注意删除凭据不等同于切换账号只是强制 Git 重新问你要身份。真正“切号”是在弹出的登录框里输入新账号对应的令牌。2.3 登录框弹出后用令牌而不是密码GitHub 从 2021 年 8 月起已经彻底移除了密码推送只允许用 Personal Access Token 做 HTTPS 认证。你现在拿账号密码往 GitHub 推必然 403。这也是网上大量403帖子的真正源头。生成令牌的路径GitHub → 右上角头像 → Settings → Developer settings → Personal access tokens → Tokens (classic)。点 Generate new token勾选repo权限如果需要删包再勾write:packages。生成后立刻复制页面刷新后就不再显示完整内容。回到 Git 登录框用户名填账号名密码粘贴令牌。GitLab 类似Preferences → Access Tokens勾选write_repository。令牌过期了会出现什么推送时报HTTP 403或者401 authentication failed。这不是账号有问题是令牌失效重新生成一个即可。2.4 不想动全局凭据改地址也能切有时候你只是想临时以另一个账号访问某个仓库不想惊动全局凭据。可以临时改远端地址在主机名前加上用户名。git remote set-url origin https://newusergithub.com/org/repo.git这样 Git 会优先以newuser身份请求仓库。不过这种方式只是“指定账号名”最后还是需要凭据管理器里有这个账号对应的令牌。还有一种写法是在 URL 里直接带令牌git push https://newuser:ghp_xxxgithub.com/org/repo.git强烈不建议这么做。令牌等于密码写进 URL 后会留在 shell 历史里一不留神就泄露。我见过不止一次因为 URL 里顺手带 token结果推完代码把整个仓库的 remote 暴露出去的案例。3. SSH 场景多账号并存与切换的正确打开方式3.1 为什么 SSH 反而不容易 403SSH 方式下认证靠一对密钥本机保存私钥平台保存公钥。连接时服务器会验证你持有与公钥匹配的私钥从而确定你的账号身份。和 HTTPS 相比SSH 最大的优势是一个私钥天然对应一个账号不存在“凭据管理器里存了旧密码”这种问题。而且密钥不会被平台莫名其妙地设个过期时间配置好之后一劳永逸。也因此SSH 是管理多账号最舒服的方式为每个账号生成一对独立密钥用配置文件指定“哪个主机用哪把钥匙”。3.2 生成一对新钥匙5 分钟搞定假设你要登录一个新账号比如公司 GitLab 账号先给这个账号生成专属密钥ssh-keygen -t ed25519 -C youcompany.com -f ~/.ssh/id_ed25519_company-t ed25519指定密钥类型安全性好长度短新平台基本都支持-C是注释建议写成能让你一眼认出的邮箱-f指定文件名多账号场景必须分开命名别全叫id_ed25519。生成完会得到两个文件~/.ssh/id_ed25519_company私钥和~/.ssh/id_ed25519_company.pub公钥。把公钥加到平台cat ~/.ssh/id_ed25519_company.pub复制输出内容到 GitHub → Settings → SSH and GPG keys → New SSH key粘贴保存。GitLab 在 Preferences → SSH Keys 里。3.3 一个 config 文件管好所有账号如果多个账号共用默认密钥名SSH 连接时就会互相打架。解决办法是编辑~/.ssh/config为每个主机或每个别名明确指定私钥Host company HostName gitlab.com User git IdentityFile ~/.ssh/id_ed25519_company IdentitiesOnly yes Host personal HostName github.com User git IdentityFile ~/.ssh/id_ed25519_personal IdentitiesOnly yes关键点在最后一行IdentitiesOnly yes它强制 SSH 只使用配置里指定的密钥而不是ssh-agent里缓存的所有密钥挨个试。如果不加这个选项两台主机都要求认证时SSH 会把所有私钥按顺序提交平台匹配不到就会拒绝连接或直接 403。配置好之后仓库地址也得跟着改# 原来是 gitgithub.com:org/repo.git # 改成 gitpersonal:org/repo.git主机名从github.com换成了配置里的别名personal。这样做的好处是切换账号只是换一个 Host 别名完全不用碰全局配置也不会有“上一个账号残留”的问题。3.4 ssh-agent 的坑新旧钥匙打架很多人配好了 config但执行ssh -T gitgithub.com一看还是旧账号的名字Hi old_user! Youve successfully authenticated, but GitHub does not provide shell access.这多半是 ssh-agent 缓存了旧私钥。SSH 客户端默认会优先使用 agent 里已有的密钥即使 ocnfig 里指定了新密钥也可能被旧密钥抢先。解决办法# 清空 agent 缓存 ssh-add -D # 把新私钥加进去 ssh-add ~/.ssh/id_ed25519_company # 再测试 ssh -T gitcompany看到新的账号名就说明切换成功了。另外还有一个细节第一次连接新别名主机时SSH 会提示无法确认主机真实性问你是否继续连接。这是正常的首次指纹确认核对下平台官方提供的指纹串没问题后输入yes即可。这不是安全问题只是 SSH 在尽通知义务。4. 403 问题排查清单与高频现场4.1 三步定位法看地址、看账号、看令牌遇到 403 不要慌按顺序做三步基本能定位问题。第一步看地址git remote -v确认走的是 HTTPS 还是 SSH这条决定后面所有排查方向。第二步试连接git ls-remote origin这个命令只做远端通信不做代码变更安全且快速。观察报错内容是denied to 某用户还是纯粹的403 Forbidden直接决定是查权限还是查令牌。第三步去平台仓库后台看成员列表GitHub仓库 Settings → Collaborators / Manage accessGitLab仓库 Settings → Members确认你的账号是否还在名单里、权限是不是Write。很多时候根本不是配置问题是管理员把你移出了团队或者仓库改成了私有而你的新账号还没被加进去。4.2 高频 403 场景速查表场景典型报错解决思路账号被移出团队denied to old_user找管理员在仓库后台重新加人并给Write权限令牌过期或吊销The requested URL returned error: 403重新生成 Personal Access Token替换凭据还在用密码推送Support for password authentication was removed改用 PAT 令牌密码只用于网页登录私有仓库但路径写错fatal: repository not found或 403确认仓库是否私有、路径拼写是否正确、账号是否有访问权账号只有只读权限denied to 账号换有写权限的账号或在仓库后台调整角色平台区域策略token exchange failed: 403 forbidden: country...服务端按访问来源做风控和 Git 配置无关按平台合规要求处理公司网络代理拦截fatal: unable to access 403检查git config --global --get http.proxy确认代理白名单是否包含代码平台域名GitHub 组织强制 SSO403但账号在名单内在令牌管理页选择“Configure SSO”授权该令牌给组织每一条都值得展开说。尤其是令牌类问题我见过太多人把过期令牌当成“密码被改”反复重装 Git 都没用最后发现就是去后台点一下“重新生成”的事。4.3 自建 GitLab / 内网场景的切换差异公司自建的 GitLab 往往开启了 LDAP 账号体系。这时候“切换账号”不是改 Git 配置而是去域控系统确认账号是否被停用、是否同步到了 GitLab。常见状况是离职同事的 LDAP 账号被禁用后你借他的账号拉代码推送时会突然 403因为域控那边的账号已经失效了。还有一类内网场景仓库走的是 SVN 而不是 Git。不少人会问“为什么我 SVN 能 checkout 代码但是提交代码时提示某一层上级目录没有权限”这里和 Git 的仓库级权限不同SVN 权限是按目录路径递归配置的。如果你对某个子目录有读写权限但对父目录没有写权限checkout 没问题commit 时 SVN 检查路径链上的每一级父目录没过就被拦下来。解决方式让管理员在版本库的authz权限配置里给对应路径加上写权限。另外自建 GitLab 的令牌命名和 GitHub 也不太一样GitLab 在Access Tokens里生成权限范围要勾write_repository而且很多企业会设置令牌的最长有效期到期后同样会遇到 403。提前在平台设置里看看到期时间别等报错再查。4.4 切换成功后的“确认四连”切完账号别急着推代码先确认真的切对了。我习惯按顺序跑四步# 1. 确认提交作者信息 git config user.name git config user.email # 2. 确认远端地址没被改乱 git remote -v # 3. 确认 SSH 认证身份仅 SSH 场景 ssh -T gitpersonal # 4. 确认能正常访问远端 git ls-remote origin有人会问提交作者信息user.name/user.email和远端认证账号一定要一致吗从技术上讲不强制一致只要远端认证通过推上去的 commit 作者可以写成任何人。但从团队协作和审计角度看建议保持一致否则代码提交记录会变得很难追溯。尤其是在公司场景提交作者最好绑定公司邮箱别把个人邮箱留在企业仓库里。5. 我的避坑经验与长期习惯聊最后一堆经验全是真实折腾出来的。第一永远不要把令牌写进 URL 或全局配置。令牌等于密码一旦出现在git remote set-url里shell 历史、日志、甚至截图都可能泄露。泄露了就去平台立刻 revoke不要有任何侥幸。第二全局user.name和user.email不要乱设。如果你同时维护个人项目和公司项目建议在每个仓库目录下单独设置而不是设一个全局值。这样个人仓库的提交不会带公司邮箱公司仓库也不会带个人邮箱后续审计和气都顺。第三同一台电脑能用 SSH 就用 SSH。HTTPS 切换账号麻烦的根源是凭据管理器太隐蔽Windows 上尤其明显老的凭据删不干净就会一直 403。SSH 用密钥对天然区分账号配合~/.ssh/config里的别名切换账号只是进不同目录的问题根本不碰全局状态。第四403 的报错信息本身就是答案。不要急着百度报错先看服务端返回的英文全文。denied to X是权限问题token expired是令牌问题password authentication removed是认证方式问题。90% 的 403 在读完报错后就知道怎么解了。第五别删除known_hosts反应过激。很多人遇到 SSH 首次连接提示就以为出事了直接删文件。实际上只要确认指纹是对的正常输入yes就行。真正需要警惕的是“指纹变了但你没换过服务器”的情况那才有可能存在中间人风险但这是另一回事了。最后分享一个个人习惯我在本机准备了两套密钥公司一套、个人一套通过~/.ssh/config分别映射到公司的 GitLab 和个人 GitHub 上。每次新建项目时复制git clone地址前先把 Host 改成对应别名然后git remote -v确认一遍。这套流程跑顺了之后“切换登录账号”这个概念在我这里基本消失了——不是切换而是各走各的通道天然不冲突。如果你现在正被 403 折磨建议按这个顺序处理看报错 → 确认通道 → 清凭据/换密钥 → 重新测试。大多数问题都出在前两步真正需要动代码仓库权限的反而是少数。
返回列表