尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Git认证失败排查:公钥设置与Access Token完整解决路径
做后端或运维的同学大概率被这句报错“问候”过Incorrect username or password ( access token )。它经常在拉取代码、推送分支、更新子模块的时候突然蹦出来明明密码是对的公钥也配好了Git 却死活不认账。这篇文章就围绕代码托管平台最让人头疼的两个认证问题展开公钥的设置与修改以及access token 导致认证失败时的完整解决路径。我会把 HTTPS 和 SSH 两条链路分开讲先把报错的根源拆清楚再给出可以直接抄的实操步骤顺便把我踩过的坑和总结出来的排查顺序都交代清楚。不管你是刚入门的新手还是被这个问题卡了一下午的人按这个思路走基本能自己定位和修复。1. 先搞懂报错到底在说哪层认证1.1 同一句报错两种完全不同的原因很多人看到Incorrect username or password的第一反应是“我是不是密码改过忘了”于是先去网页端改密码改完回来继续拉代码结果照样报错。说实话我第一次遇到这个问题时也干过这种蠢事折腾了快一个小时才反应过来Git 在这里报的错不是“你的密码不对”而是“你这次请求携带的凭据没有通过服务端校验”。这里的关键在于Git 的远程地址有两种完全不同的协议形态。一种是 HTTPS走的是 HTTP 基础认证服务端只认用户名 密码或者用户名 access token另一种是 SSH走的是公钥认证机制服务端通过你预先添加的公钥来判断本地是否持有配对的私钥。所以那句Incorrect username or password绝大多数情况下只会出现在 HTTPS 协议下是服务端对你 HTTP Basic Auth 的通用拒绝信息。注意它不会告诉你到底哪个字段错了也不会区分你是填错用户名、填错密码、还是 token 过期。只要认证没过去就是这同一句话。而 SSH 如果失败报的通常是Permission denied (publickey)。因此看到报错之后的第一件事不是去折腾公钥而是先确认当前 remote 地址用的到底是什么协议。1.2 为什么 access token 是 HTTPS 的“密码”而不是公钥很多教程都会讲“把公钥添加到平台”于是不少人就形成了一个印象只要公钥配好了怎么拉代码都没问题。这个理解在 SSH 协议下成立但换到 HTTPS 协议下就完全不是一回事。你可以把 SSH 公钥理解成“门禁卡系统里的卡号”服务器那边记录了你的卡号你的电脑里保存着对应的“刷卡动作”。HTTPS 则像是“密码锁”服务器不关心你有没有门禁卡它只关心你输入的用户名和密码是否正确。因为现在很多代码托管平台出于安全考虑已经不允许直接用账号登录密码来执行 Git 操作而是要求你在网页端手动生成一个私人令牌也就是 access token / 私人令牌再把令牌当作 HTTPS 的密码来用。这也是为什么你的 SSH 公钥设置得再完美只要 remote 地址是 HTTPS出现Incorrect username or password ( access token )就是家常便饭。因为你根本不是在跟公钥打交道而是在跟 token 打交道。标题里把“公钥的设置和修改”和“access token 报错”放在一起其实就是两种高频场景的合集SSH 链路要看公钥HTTPS 链路要看 token两个都得会。1.3 30秒判断你当前用的是哪种认证方式判断方法非常简单打开终端在任意一个 Git 项目目录下执行git remote -v看到类似这样的输出origin https://example.com/username/repo.git (fetch) origin https://example.com/username/repo.git (push)那说明当前项目走的是 HTTPS你要去处理 access token 和本地凭据缓存的问题。如果输出是origin gitexample.com:username/repo.git (fetch) origin gitexample.com:username/repo.git (push)那才是 SSH你要去检查公钥、私钥、ssh-agent 这些东西。这一步 30 秒就能完成但它决定了你后续排查的方向。很多人一纠结就往公钥那一侧钻结果方向错了时间全浪费了。2. 公钥的设置从生成到生效的完整链路2.1 生成密钥对之前先理解公钥和私钥的分工公钥和私钥的关系我用一个生活化的类比来说公钥是锁私钥是钥匙。你把锁公钥交给平台挂在你的账号名下钥匙私钥留在你本地绝对不传给任何人。SSH 握手的时候服务器那边拿着你公开的“锁”向你发起一个挑战如果你能证明你持有对应的“钥匙”就放你通过。服务器只知道公钥不知道你的私钥你的私钥也不会在网络传输中出现。这里最重要的一个原则就是公钥可以随便给别人看但私钥一旦泄露就等于你这把锁的钥匙被人配了一把任何持有私钥的人都能以你的身份访问代码仓库。所以私钥文件一定要注意保护不要放到公共网盘更不要随手粘贴到聊天工具里发给别人。2.2 命令行生成密钥对的实操在本地生成密钥对推荐优先使用 Ed25519 算法它的安全性高密钥短验证速度快。命令是ssh-keygen -t ed25519 -C your_emailexample.com-C后面的内容是一个注释通常写你的邮箱方便在平台后台识别这把公钥是谁的。执行后终端会问你要保存到哪个文件Generating public/private ed25519 key pair. Enter file in which to save the key (/home/yourname/.ssh/id_ed25519):直接回车使用默认路径即可。接着会提示输入口令passphraseEnter passphrase (empty for no passphrase):建议设置一个强口令。虽然每次 SSH 连接都要输一遍口令有点烦但后面搭配 ssh-agent 就能省掉重复输入。口令的作用很大即使私钥文件不小心被人拿走没有口令他也用不了。如果你的协作环境比较老某些服务器只支持 RSA 密钥那就改用ssh-keygen -t rsa -b 4096 -C your_emailexample.comRSA 用 4096 位长度基本是标配低于 2048 的已经不推荐了。生成完成后~/.ssh目录下会出现一对文件id_ed25519或id_rsa是私钥id_ed25519.pub或id_rsa.pub是公钥。这两个文件的权限也要注意私钥权限不能太开放否则 SSH 会拒绝使用它。2.3 公钥添加进平台私钥交给本机 ssh-agent公钥的内容可以用下面的命令查看cat ~/.ssh/id_ed25519.pub输出是一整行以ssh-ed25519 AAAA...开头的字符串。你需要把这整行复制下来然后登录代码托管平台的网页端找到“安全设置”或者“SSH 公钥管理”之类的入口填一个便于识别的标题比如“我的笔记本”再把公钥粘贴进去保存。接来下是本机私钥的管理。为了让 ssh-agent 帮你管理私钥可以在终端执行eval $(ssh-agent -s) ssh-add ~/.ssh/id_ed25519ssh-add会把私钥加载到内存中的 ssh-agent 进程里。如果你设置了口令这一步骤会询问口令加载之后只要电脑不重启后续 SSH 连接都不需要再输口令。macOS 用户还可以用ssh-add --apple-use-keychain把私钥写进钥匙串。有一个非常容易犯的错误把公钥当私钥传给了平台或者复制时少复制了几个字符导致后台显示的公钥不完整。粘贴公钥的时候一定要复制完整的一行不要手动换行不要加多余空格。2.4 用 ssh -T 验证链路是否打通配置完成后验证是否生效ssh -T gitexample.com如果看到类似Hi 用户名! Youve successfully authenticated的提示说明 SSH 公钥链路已经打通。如果看到Permission denied (publickey)就说明服务器没能识别你的私钥。这时候按顺序排查确认本机~/.ssh/id_ed25519这个文件存在且~/.ssh/config没有干扰项。确认平台账号里已经添加了对应的公钥而且公钥内容与本地id_ed25519.pub完全一致。如果配置了多个私钥可以用-i手动指定ssh -T -i ~/.ssh/id_ed25519 gitexample.com确认~/.ssh/known_hosts里面没有记录的旧主机指纹和当前服务器不一致的情况可以把对应行删掉再试一次。这一条链路要完整走通才算真正解决了 SSH 下的认证问题。3. 公钥的修改与多设备场景下的管理3.1 什么时候需要修改公钥很多人以为公钥设置好之后就一劳永逸了实际上它也是需要维护的。常见触发修改公钥的场景有这么几类换了新电脑想把旧电脑上的访问权限收回来。旧设备丢失或怀疑私钥泄露需要立即让旧公钥失效。团队账号或者个人账号更换了常用邮箱想更新公钥注释。平台后台误删了公钥导致本地 SSH 连接突然失败。一台电脑上要同时管理多个代码托管平台的多个账号需要为不同场景准备不同密钥。关键在于代码托管平台通常允许一个账号添加多个公钥所以“修改”不一定是把旧的删掉再新增一个有时候只是“新增一个新公钥”而已。在删除旧公钥之前先想清楚这台设备上还有没有正在使用的自动化任务比如定时脚本、CI/CD 机器别一头热把旧公钥删了结果别的机器全断连。3.2 修改公钥的完整动作如果需要修改公钥我建议按以下顺序操作在本地重新生成一对新的密钥ssh-keygen -t ed25519 -C new_commentexample.com -f ~/.ssh/id_ed25519_new查看新公钥内容cat ~/.ssh/id_ed25519_new.pub登录平台后台把旧公钥删除把新公钥添加进去。如果你只是想新增一台设备可以保留旧公钥直接添加新设备对应的公钥。在本机配置好新的私钥路径加载到 ssh-agentssh-add ~/.ssh/id_ed25519_new验证新密钥ssh -T -i ~/.ssh/id_ed25519_new gitexample.com最后在项目目录里拉取一次代码确认远端操作正常。这里有一个细节需要注意如果把旧公钥删掉了但本地 git 项目里某些 remote 地址仍然指向旧的 SSH 别名或者 SSH config 里还绑定了旧私钥路径即使公钥已经换了连接还是会走错。所以修改公钥之后最好把~/.ssh/config和项目的.git/config都整体检查一遍。3.3 多台设备的公钥管理一份公钥的复制与多账号配置多台设备用同一份私钥在技术上是可以的但我个人不推荐。每台设备生成独立密钥对再把对应的公钥添加到同一个平台账号下才是更稳妥的做法。这样即使某台设备出了问题其他设备不受影响只需要在后台删除出问题的那台公钥即可。当然如果你确实需要在一台新电脑上快速复用旧电脑的私钥也不是不能做。把旧电脑上的私钥文件复制到新电脑的~/.ssh/目录下注意修改文件权限为600然后加载到 ssh-agentchmod 600 ~/.ssh/id_ed25519 ssh-add ~/.ssh/id_ed25519但这条路只适合在你自己完全可信的设备之间做而且私钥一定要有口令保护。有一次我把私钥从主力机复制到备用机忘了一口令是空的后来备用机丢了只能立刻去平台后台把旧公钥删掉重新生成一对。踩过那次坑之后我再也没有复制过私钥全部改为每台设备独立生成。3.4 使用SSH config解决多密钥切换当同一台电脑要连接两个不同的平台账号或者要同时使用公司内部 Git 服务和个人的代码托管平台时默认的id_ed25519往往不够用。因为在 SSH 连接时客户端默认只会尝试加载符合默认名称的私钥如果服务器不认识这把私钥对应的公钥连接就失败。这时候可以在~/.ssh/config文件里做多主机配置Host work HostName git.example.com User git IdentityFile ~/.ssh/id_ed25519_work Host personal HostName git.example.org User git IdentityFile ~/.ssh/id_ed25519_personal这样配置后远程地址就可以写成git remote add origin gitwork:username/repo.git或者git remote add origin gitpersonal:username/repo.gitSSH 会根据别名work和personal自动选择对应的私钥。注意HostName是你真实要连接的服务器地址User在绝大多数 Git 托管平台上都是git。这个文件里也可以统一设置StrictHostKeyChecking ask等安全选项避免第一次连接时被中间人攻击。4. access token 的生成与报错实战排查4.1 token正确生成为什么还是报错tsc 只要 remote 是 HTTPS就会遇到Incorrect username or password ( access token )哪怕你已经按照说明生成了 token也还是可能报错。根据我的经验常见的隐藏原因有这么几个token 复制不完整或者多复制了一个空格。很多网页端在复制 token 时会在末尾带入换行符粘贴到终端里就会出现问题。token 权限不够。有的平台生成 token 时会让用户勾选权限范围比如projects、repository、read/write如果只勾了读权限你执行 push 操作当然会失败。token 设了有效期且已经过期。有些平台强制要求设定有效期过期之后不会自动续期只能重新生成。本地凭据管理器缓存了旧密码。这是最隐蔽的一个原因系统会优先使用缓存里的凭据而不会弹窗重新询问。用户名填错。有的平台要求用户名有的平台要求邮箱有的平台两种都接受但如果你填的格式不对照样失败。token 中包含、/、:等特殊字符直接拼接在 URL 里时没有编码导致 URL 解析出错。4.2 让remote URL切换到带token的HTTPS地址最简单粗暴的方式是重新设置 remote 地址把 token 直接写在 URL 里git remote set-url origin https://username:your_tokenexample.com/username/repo.git然后执行git pull验证。但我不推荐这种做法因为 token 会明文写在.git/config文件里只要有人能拿到你的仓库目录就等于拿到了 token。更好的做法是先把 remote 地址改成不带 token 的 HTTPS 地址git remote set-url origin https://example.com/username/repo.git然后执行git pull这时候 Git 会弹出交互式认证窗口用户名填你的平台用户名密码栏粘贴 token。凭据管理器会记住新的 token后续操作就不再报错。如果你非要手动修改.git/config也很简单找到[remote origin]段把url改成对应的 HTTPS 地址即可。注意 URL 的格式https://后面先跟用户名用户名和 token 之间用冒号再跟和服务端地址顺序不能反。4.3 清空本地凭据缓存强制重新认证如果你已经重新生成了 token但操作时还是提示旧凭据不对那基本可以确定是本地缓存的问题。不同操作系统清理方式不太一样。Linux 下如果使用store模式凭据会保存在~/.git-credentials文件里直接把对应行删掉或者执行git config --global --unset credential.helper如果使用cache模式可以等待超时自动过期也可以执行git credential-cache exitWindows 下最常见的是“凭据管理器”缓存打开控制面板 → 用户账户 → 凭据管理器 → Windows 凭据找到包含代码托管平台地址的条目删除即可。也可以用命令行cmdkey /list | findstr /i example.com找到目标后执行cmdkey /delete:targetgit:https://example.commacOS 下则是钥匙串访问在“钥匙串访问”App 里搜索平台地址把对应条目删除或者用命令git credential-osxkeychain erase按照提示输入主机名和协议后回车再清掉。清完缓存之后再次执行git pullGit 会重新要求输入用户名和密码。这时候填新的 token基本就能通过了。4.4 问题速查表场景报错信息大概率原因解决办法SSH 连接被拒Permission denied (publickey)公钥未添加 / 私钥不匹配检查后台公钥、私钥路径、ssh-agentSSH 卡在口令输入Enter passphrase for key私钥设置了口令未加载到 agent执行 ssh-addHTTPS 拉取报密码错Incorrect username or password ( access token )token 过期或权限不足重新生成 token检查权限HTTPS 拉取报密码错Incorrect username or password ( access token )本地凭据缓存旧值清理凭据管理器 / 钥匙串新电脑无法 clonePermission denied (publickey)新电脑没有私钥生成新密钥添加公钥到平台同一台电脑多账号冲突Permission denied (publickey)SSH config 未配置加载错私钥编写 ~/.ssh/config 指定 IdentityFile平台后台公钥删了Permission denied (publickey)公钥已失效重新添加公钥这张表是我自己整理的不一定覆盖所有平台的所有细节但绝大多数情况都能在里面找到对应方向。5. 一次完整排查实录5.1 现场现象前阵子有个朋友 A 找我说他在新电脑上 clone 公司内部的代码仓库时遇到了Incorrect username or password ( access token )的报错。他在旧电脑上是能正常操作的新电脑也按照教程生成了 SSH 公钥并添加到了平台后台但 clone 依然失败。当时他的第一反应是公钥没配好又去后台检查了几遍还重新生成了一次公钥结果问题照旧。我让他把报错现场发过来代码如下git clone https://example.com/username/repo.git Cloning into repo... remote: Incorrect username or password ( access token ) fatal: Authentication failed for https://example.com/username/repo.git到这里其实问题已经很明确了clone 使用的是 HTTPS 地址不是 SSH 地址所以公钥无论怎么配都是白搭因为服务端走的是 HTTP Basic Auth根本不看公钥。5.2 逐步排查与处理结果我按下面的顺序带他处理第一步确认 remote 协议。因为 clone 命令里写的就是 HTTPS所以直接确定是 HTTPS 认证问题。第二步检查 token 权限。他登录平台后台重新生成一个新的 token并确保勾选了仓库读写权限。第三步清理本地凭据缓存。新电脑虽然没有缓存旧凭据但为了保险还是把凭据管理器里可能有的杂项清理了一遍。第四步执行 clone 命令不要直接改 remote而是让 Git 弹出认证窗口。在提示输入用户名时填平台用户名提示输入密码时粘贴刚才生成的 token。这一次 clone 成功。事后我问他为什么会在新电脑上跑去配置 SSH 公钥他说看了一些教程说是先配公钥再 clone。实际上教程里的公钥配置主要服务于git开头的 SSH 地址他拿 HTTPS 地址去操作自然是南辕北辙。这也是我反复强调“先看 remote再决定动公钥还是动 token”的原因。6. 日常维护建议6.1 把身份认证信息从 URL 里剥离很多人为了省事喜欢把用户名和 token 直接写进 remote URL。这样做短时间内能通过认证但存在两个隐患一是 token 明文留存二是后续只能手动改 URL 才能更换凭据。我个人的做法是统一用不带凭据的 HTTPS 地址让系统凭据管理器来存 token这样每次换 token 只需要清理一次缓存不需要改动项目配置。6.2 别把所有密钥都用默认文件名当你有多个代码托管平台账号时如果所有密钥都叫id_ed25519SSH 会默认使用同一个私钥去连接不同服务器很容易出现“在这台机器上配了 A 平台的公钥连 B 平台时却用了 A 平台的私钥”这种错乱。给每个平台、每个账号起不同的密钥文件名再通过~/.ssh/config做映射是更清晰的做法。6.3 定期清理失效公钥我见过不少团队成员的平台账号下挂着三四把公钥其中一半是已经不用了的旧电脑生成的。公钥越多安全隐患就越大。建议每隔半年检查一次后台公钥列表把不认识的、不再使用的公钥删掉并为每把公钥写上清晰的备注比如“2024款笔记本”“公司台式机”方便日后识别。6.4 关于报错信息的文字游戏Incorrect username or password ( access token )这句报错真的很误导人它把所有认证失败都归成同一句话。实际排查时不要被这句话牵着走。你可以把它拆成三个问题协议对不对HTTPS/SSH、凭据新不新token 是否过期、本地缓存的凭据有没有被系统优先使用。按这个顺序排查基本五分钟就能定位问题。我个人在实际操作中的体会是认证问题最怕的就是“凭感觉乱试”。先看git remote -v再用ssh -T测 SSH 链路最后才碰 token 和缓存这套顺序我用了很久几乎没有失手过。希望这篇内容也能帮你少走一些弯路。
RELATED

相关推荐

基于Docker部署JumpServer堡垒机的实操避坑指南

基于Docker部署JumpServer堡垒机的实操避坑指南

跳板机不是堡垒机,堡垒机也不是一个只能用来跳来跳去的工具。我第一次接触JumpServer,是团队里服务器权限乱成一锅粥的时候——root密码在五六个人手里传来传去,生产环境今天有人改个配置,明天有人跑个脚本,出了故障谁…

📅 2026/10/21 4:15:54
knowledge-work-plugins:知识工作流的可编程原子化操作系统

knowledge-work-plugins:知识工作流的可编程原子化操作系统

1. “knowledge-work-plugins”不是插件市场,而是一套知识工作者的数字工作流操作系统“knowledge-work-plugins”这个标题乍看像某个开源仓库名,或是某款笔记软件的插件合集——但如果你真这么理解,就错过了它背后最本质的转向:它…

📅 2026/10/21 4:15:54
T-Rex2 开放集目标检测快速上手:免训练的文本-视觉提示检测指南

T-Rex2 开放集目标检测快速上手:免训练的文本-视觉提示检测指南

T-Rex2 开放集目标检测快速上手:免训练的文本-视觉提示检测指南 【免费下载链接】T-Rex [ECCV2024] API code for T-Rex2: Towards Generic Object Detection via Text-Visual Prompt Synergy 项目地址: https://gitcode.com/GitHub_Trending/tre/T-Rex T-Re…

📅 2026/10/21 4:15:54
MORE NEWS

更多资讯

📰

OFDM峰均比抑制实战:SLM选择性映射原理与Python仿真代码解析

简介:这份SLM方法降低PAPR的仿真代码,面向OFDM通信系统研究与学习人群,针对多载波传输中峰均功率比过高的问题,提供完整的信号级映射(SLM)降PAPR实现参考。代码基于MATLAB编写,压缩包仅含1个m脚…

📰

大模型Function Calling实战:从JSON解析困境到稳定工具调用

做LLM应用开发的人,大概率都经历过这一段尴尬:辛辛苦苦把用户指令塞给大模型,让它输出一段JSON用于触发业务动作,结果模型生成一个带Markdown注释的、缺字段的、甚至多出幻想字段的“假JSON”,程序解析直接报错。我当初…

📰

从栅格地图到导航接入:机器人地图服务模块设计与实操

1. 项目定位:为什么机器人项目需要一个独立的地图模块做机器人导航最怕什么?不是算法调不通,而是当你把传感器、底盘、规划器都调好之后,发现整套系统被一张乱七八糟的地图卡住了。lingbot-map这个项目,就是专门解决这…

📰

Spring Boot海鲜烧烤商城系统设计:从数据库到订单库存的完整实践

每个做毕设或课设的同学,大概率都见过这类标题:“基于Spring Boot的XX商城系统”。我的待办事项列表里常年躺着类似的需求,其中“springboot167基于Java的水产品海鲜烧烤商城购物网站系统设计与实现”算是比较典型的电商类题目。你第一眼看到…

📰

Spring Boot海鲜烧烤商城开发实战:从数据库设计到订单部署全覆盖

开篇先说实话,这个标题我看着挺亲切的——“基于Java的水产品海鲜烧烤商城购物网站系统”,一看就是典型的Spring Boot单体电商项目。别觉得它“只是毕业设计”就小看它,能把一个电商系统完整做下来,从前端页面到后端接口、从购物车…

📰

从技能清单到可复现体系:构建可迁移技能栈的实操框架

1. 从“skills”这个词说起:为什么它突然成了硬通货“skills”这个词,放在三五年前,大家聊起来多半还是简历上那一栏“专业技能”——写几个关键词,凑个版面,面试官扫一眼就过去了。但现在不一样了。你去看各种社区、招…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬