
1. 报错场景与根因分析最近连续有好几个人私信问我同一个问题都是项目里在跑git clone或git push的时候突然弹出一行看起来很严肃的提示remote: Invalid username or token. remote: Password authentication is not supported. fatal: unable to access https://xxx/xxx.git/: The requested URL returned error: 403如果你是在拉取或推送私有仓库时遇到的这个报错大概率不是网断了也不是仓库权限被回收而是认证方式没跟上服务端的新规则。很多人在第一次看到Password authentication is not supported时都很懵以为是自己密码输错反复重试之后依然被拒。这个报错背后其实是一个很典型的机制升级代码托管平台已经逐步关闭了“用户名密码”直接访问仓库的通道改成了更安全的令牌认证或者 SSH 密钥认证。下面我把整个链路拆开讲清楚从错误信息本身到三种可行方案再到实际踩坑记录一次性帮你理顺。1.1 错误信息到底在说什么先看报错里的几行关键内容remote: Invalid username or token.服务端在明确告诉你它收到了认证请求但无法识别提交过来的用户名或令牌。这句话表达得很克制但实际含义通常是“你给的凭证不对”或者“凭证根本没有被当成令牌来解析”。remote: Password authentication is not supported.这句话才是重点。服务端是在说我不支持密码认证了请换用令牌或者其他方式。如果你在终端提示里输入的是账号密码不管输得对不对都会被直接拒绝因为服务端在认证阶段就关掉了这个通道。fatal: unable to access ... The requested URL returned error: 403这是 Git 客户端的最终表现。403 代表服务端理解请求但拒绝执行。到这里整个拉取或推送就被中断了。很多人把 403 误认为权限不足跑去改仓库权限折腾半天也没用。真正的逻辑链条是服务端不支持密码认证 → 你还在用密码/错误的用户名 → 认证失败 → 返回 403。只要把认证方式换成令牌或 SSH问题通常就迎刃而解。1.2 为什么服务端要禁用密码认证早期很多私有仓库都支持直接在 HTTPS 地址里填写用户名和密码确实简单方便但安全问题越来越多。密码一旦泄露意味着整个账号完全暴露尤其当用户在不同平台复用同一个密码时风险更大。而且密码不适合做细粒度授权要么能访问全部仓库要么全部不能访问很难做到只给某个项目一个临时只读权限。令牌是对密码的一种替代机制。它本质上是一串随机生成的字符串但可以设置有效期、可以限定权限范围、可以随时单独吊销。就算某个令牌泄露也不会影响到账号密码也不牵连其他设备上的令牌。SSH 密钥也是类似思路用户手里保留私钥平台上只存公钥私钥不出本地安全性更高。所以看到Password authentication is not supported的时候不要觉得是服务商故意为难你这是行业整体的安全趋势。你不该再去找“还能不能用密码”的办法而应该顺势切换到新机制。1.3 哪些场景最容易触发这类报错根据我平时在各种环境里排查的经验最容易踩到这个报错的有四类场景场景表现核心原因新环境首次 clone 私有仓库刚装完 Gitclone 到一半报 403远程地址是 HTTPS本地没有配置令牌换电脑或重装系统后 push凭据管理器里没有保存新凭证没生成或没填入令牌开启了双重认证的老账号密码明明能登录网页Git 却连不上双重认证下密码必须配合令牌使用自动化脚本/CI 里使用旧密码脚本里写死用户名:密码服务端已禁用密码认证必须改用令牌在这些场景里报错信息往往一闪而过不会给你太多上下文。你需要在脑中建立一条排查顺序先确认远程地址再确认认证方式最后再检查令牌权限和有效期。2. 方案一先用个人访问令牌顶上去如果你的第一诉求是“赶紧让我把代码拉下来”那最快的方法就是生成一个个人访问令牌用令牌代替密码。个人访问令牌在不同平台有不同的叫法有的叫访问令牌有的叫私人令牌英文一般都叫 Personal Access Token缩写 PAT。不管名字怎么变生成和使用的逻辑是相通的。2.1 令牌应该怎么生成生成令牌的入口一般在代码托管平台的账户设置里。具体路径通常是这样登录平台网页端点击右上角头像或菜单进入账号设置。找到“开发者设置”“安全设置”或类似的入口。找到“Personal access tokens”或“访问令牌”页面。点击“Generate new token”系统会要求你先输入一次账户密码或完成二次验证。进入令牌配置页面设置令牌名称、有效期和权限范围。权限范围里勾选repo这类仓库读写权限如果涉及到 CI/CD 或自动化工作流可能还要勾选workflow等额外权限。点击生成后页面上会出现一串明文令牌记得立刻复制保存。很多页面在你跳转之后就不允许再次查看完整令牌了。这里有个细节值得多说几句令牌生成时权限范围务必按最小权限原则选。比如你只用来 clone 公开仓库的某些配置那也许只需要只读权限如果平时还要拉取私有仓库并推送代码至少需要repo权限。一次把权限拉到最大虽然方便但一旦泄漏破坏范围也更大。2.2 在 clone 和 push 命令里使用令牌拿到令牌之后你可以用下面几种方式把它传给 Git。第一种直接在远程地址里带上用户名和令牌git clone https://你的用户名:你的令牌host/组织名/仓库名.git这种写法虽然直观但我并不推荐日常使用。令牌明文出现在命令里很容易被终端日志、shell 历史记录甚至是屏幕分享时看到。只适合临时测试或者服务器上一次性初始化。第二种用不带令牌的地址让 Git 单独提示你输入用户名和令牌git clone https://你的用户名host/组织名/仓库名.git执行之后 Git 会提示输入密码这时候把令牌粘贴进去作为密码即可。用户名如果输错后面令牌填得再正确也没用。第三种也是我认为最可控的方式是不在 URL 里预设用户名直接在终端交互提示中输入git clone https://host/组织名/仓库名.git Username: 你的用户名 Password: 你的令牌这样可以避免 shell 历史记录里留下令牌痕迹也便于观察到底是哪一步认证出了问题。push 和 clone 的认证逻辑一致。第一次 push 之后如果你配置了凭据管理器Git 会记住这次使用的用户名和令牌后续命令就不需要重复输入了。2.3 令牌的权限范围与有效期别贪省事令牌不是永久的。常见的有效期选项是 7 天、30 天、90 天或自定义时长。建议根据自己的实际需求来设置。如果这个令牌是给个人电脑长期开发用的可以设得长一点但至少要有一个明确的到期日强迫自己在到期前重新走一遍认证流程。如果是给临时任务或 CI 用的短期令牌更合适。权限范围也要看清楚。不要一上来就把所有权限全部勾选。很多平台把仓库读、仓库写、删除、分支管理、工作流等权限分开列出来了。你只需要普通 push 的话重点勾选仓库写权限。如果你从不在命令行里操作 workflow 配置没必要把那个权限也打开。我之前就犯过一个错误为了省事生成一个全权限令牌放在配置文件夹里结果脚本被误提交到了公共仓库令牌随仓库一起暴露。好在及时发现后吊销并重新生成才没有造成实际损失。从那以后我的令牌都严格按照“最小够用”来配置。提示令牌一旦泄露无论过期时间有多远都要立刻去平台设置里吊销并重新生成。不要存在项目目录里更不要提交到仓库。3. 方案二换成 SSH一次性根治如果你已经受够了令牌过期、权限勾选、输入一堆字符串这些麻烦SSH 是更省心的长期方案。SSH 不像 HTTPS 那样每次都要考虑“这次该用哪个用户名和密码”而是靠一对公私钥完成身份认证。私钥放在你本地公钥放在平台账户里之后 clone、push、pull 都走加密通道不需要在命令中反复输入凭证。3.1 为什么建议直接把线路切到 SSHHTTPS 加令牌虽然能解决问题但属于“修复症状”。SSH 的作用更像是“换一条更稳的路”。首先是免密体验。SSH 密钥配置好之后除非你给私钥设置了密码短语否则后续所有 Git 操作都不会再弹输入框。对于频繁 push 的人来说这个体验差距非常明显。其次是权限隔离。一个 SSH 密钥对应一个账户你可以在不同机器上生成不同的密钥对分别加入不同账户。即使某一台电脑上的私钥泄漏你也可以只删除该密钥对应的授权不影响其他设备。最后是稳定性。很多企业和学校网络策略比较严格HTTPS 端口经常被代理拦截但 SSH 的 22 端口或 443 端口相对更容易放行。这在实际工作中是个非常实用的优势。3.2 生成并配置 SSH 密钥生成密钥很简单。如果你用的是较新版本的 Git直接执行ssh-keygen -t ed25519 -C 你的常用备注命令会让你选择私钥保存路径和设置密码短语。默认路径是~/.ssh/id_ed25519如果本机之前没有生成过其他密钥直接回车用默认路径就行。密码短语这一项可以留空也可以设置一个本地口令。留空就代表完全免密设置了口令后每次使用私钥时都会要求输入一次。如果你的系统或服务端对 ed25519 支持不佳可以改用 RSA比如ssh-keygen -t rsa -b 4096 -C 你的常用备注生成完成后屏幕上会输出公钥文件路径。一般公钥是.pub结尾的那个文件。用下面的命令查看内容cat ~/.ssh/id_ed25519.pub复制这段公钥到代码托管平台的设置里找到“SSH keys”或者“SSH 公钥”页面粘贴保存。保存时会要求你为这个公钥起一个名字一般写“公司电脑”“家用笔记本”“服务器”之类便于区分的名称。密钥添加成功后先用一行命令确认连通性ssh -T githost如果配置正确你会看到类似“成功认证”或者“欢迎回来”的提示文字。如果看到权限拒绝检查公钥内容和用户名是否正确尤其注意githost里的host要替换成你实际使用的域名。3.3 把现有仓库切到 SSH对于已经用 HTTPS 克隆下来的仓库切换远程地址只需要一条命令git remote set-url origin githost:组织名/仓库名.git执行后可以验证一下git remote -v看到origin后的地址从https://...变成了git...就说明切换成功。之后你再执行git push或git pull会发现终端不再询问用户名和密码了。如果机器上有多个 SSH 密钥对应多个账户需要借助~/.ssh/config文件区分。比如Host work HostName host1 User git IdentityFile ~/.ssh/id_ed25519_work Host personal HostName host2 User git IdentityFile ~/.ssh/id_ed25519_personal配置之后clone 地址可以写成git clone work:组织名/仓库名.gitHostName是真正的平台域名IdentityFile是对应私钥路径。这样可以避免一台电脑上多个账户互相混淆。4. 方案三凭据管理器与多账户切换有些场景下你不想换 SSH只想继续用 HTTPS但又不愿意每次 push 都手动粘贴令牌。这时候凭据管理器就能发挥作用。4.1 让 Git 记住令牌减少重复输入Git 本身不自带存储能力它会把凭据委托给外部程序。常见的凭据管理器有三种git config --global credential.helper manager-coremanager-core是很多 Windows 自带 Git 环境默认的凭据管理器它会把你输入的密码或令牌保存到系统凭据保险库中。后续访问同一个远程地址时Git 自动读取并使用保存的凭据。如果你的系统没有 manager-core也可以使用 store 模式git config --global credential.helper store这个模式会在你~/.git-credentials文件中明文保存用户名和令牌。优点是配置简单缺点是安全性很差。只要有人能读到你这个文件就能直接获取你的令牌。不建议在公用电脑上使用这种模式。还有一种更灵活的做法是使用缓存模式git config --global credential.helper cache --timeout3600这种模式会在内存中缓存凭据3600 秒后失效需要重新输入。适合本机临时开发使用不会落盘相对更安全。4.2 多账户场景下凭据为什么会串使用凭据管理器后最大的坑就是多账户串号。假设你在一台电脑上同时使用两个账户分别是工作账号和个人账号。第一次 clone 工作仓库时输入了工作令牌凭据管理器记住了这个地址对应的登录信息。第二次 clone 个人仓库时由于远程域名相同凭据管理器可能会把工作令牌当作默认凭证提交过去结果报出Invalid username or token或者权限不足。解决思路有两个方向。一个是彻底抛弃 HTTPS 多账户全部走 SSH 密钥 ~/.ssh/config这个前面已经提到过。另一个方向是坚持用 HTTPS并通过 Git 的 URL 重写规则区分不同用户。比如你希望访问host平台时默认用userA可以为特定路径设置别名git config --global url.https://userAhost/.insteadOf https://host/这样在 clone 或 push 时https://host/org/repo.git会被自动改写成https://userAhost/org/repo.gitGit 就会用userA的身份去认证从而避免和userB的凭据混淆。这种方案看起来能用但维护起来比较麻烦。每次新增账户、修改用户名、切换身份都要动全局配置稍不注意就把一堆仓库的访问目标都改乱了。对于日常开发我还是优先建议用 SSH。4.3 巧用 insteadOf 规则统一切换协议除了多账户场景insteadOf还能干一件很省心的事把现有 HTTPS 地址统一转成 SSH 地址而不需要逐个仓库去git remote set-url。方法如下git config --global url.githost:.insteadOf https://host/设置之后所有指向https://host/的远程地址在 Git 内部都会被替换为githost:。这意味着你不需要改仓库的远程配置push 时就直接走 SSH 接口了。但这个规则要注意副作用。它是全局规则会作用到所有符合前缀匹配的仓库。如果你公司内部有些仓库只开放 HTTPS 入口、并不支持 SSH那么这个规则会把那些仓库也强制切到 SSH导致无法访问。碰到这种情况可以临时去掉这条全局规则或者把它改成仅针对某些仓库路径生效。git config --global --unset url.githost:.insteadOf我个人只在个人电脑上使用这种规则公司电脑上并不敢乱加因为公司内部仓库环境太复杂了。5. 常见问题排查与避坑实录前面已经把三种方案讲完了但你实际执行时大概率还会遇到一些奇怪现象。这里我把排查过程按场景整理成速查表你可以直接对照着看。5.1 令牌明明是对的还是报 Invalid username or token这个问题出现频率最高。我遇到过的原因大致有下面几种第一种用户名不对。很多平台的用户名并不是你的邮箱而是一个单独的账号名。如果你填的是注册邮箱服务端可能直接认为用户名无效。请在平台账户主页确认用户名再重新尝试。第二种令牌在 URL 里被 shell 特殊字符干扰。令牌中如果出现了!、$、、*等特殊字符未加引号时会被 Shell 解析导致实际发送的令牌已经被截断或替换。解决办法是使用单引号包裹整个 URLgit clone https://user:tokenhost/org/repo.git或者在交互提示时粘贴令牌而不是把它写在命令里。第三种令牌权限范围不够。如果你只勾选了只读权限却尝试 push服务端一样会拒绝。这种情况下报错往往是403或Invalid username or token。去平台查看令牌的权限明细确认是否包含仓库写权限。第四种令牌已经过期。尤其当你早先生成的是 7 天有效期令牌一周时间一过第二次使用时必然报错。重新生成一个即可。第五种代理或防火墙干预。某些企业网络的 web 代理会在认证环节直接返回错误导致 Git 收到的响应并不是平台实际返回的认证结果。这时可以先取消代理测试git config --global --get http.proxy如果确认开了代理临时关闭后重试。5.2 “Support for password authentication was removed”报错这个报错和Password authentication is not supported非常相似通常出现在你的远程地址还是旧版 HTTPS 形式并且命令里明显使用了密码认证。这类报错一般不是令牌配置问题而是你还没开始使用令牌。处理方式很简单确认远程地址。如果地址仍然是https://...且你的工具链还停留在密码认证阶段那就按第 2 部分生成令牌。在命令行交互提示的密码位置输入令牌避免在 URL 中明文传输。如果已经改了地址还是报错继续看下面的 5.3。5.3 明明改了 remotegit 还是走 https遇到这种问题我会依次检查三处地方。第一处仓库本身的远程地址git config --get remote.origin.url如果输出的还是https://...说明set-url没生效或者改错了仓库。重新执行一次git remote set-url origin githost:org/repo.git第二处全局配置文件里是否有insteadOf规则在捣乱git config --global -l | grep insteadOf如果有url.https://host/.insteadOf githost:之类的反方向规则它会把你刚刚改好的 SSH 地址重新换成 HTTPS。把对应规则删掉即可。第三处凭据管理器里残留的旧凭据。有些平台在同一会话中会持续使用旧的凭据导致即使远程地址换了推送时依然报错。你可以在系统的凭据管理里删除与该平台相关的凭据然后在终端里重新认证。下面是一张汇总表方便你在真实排障时逐项核对现象可能原因快速验证方法解决动作URL 里带令牌仍报错特殊字符被 shell 转义用交互方式重新输入将 URL 整体用单引号包裹令牌正确但权限不够勾选权限不足去平台查看令牌权限重新生成或补权push 时被拒绝令牌只读 / 已过期查看令牌有效期重新生成短期令牌SSH 测试失败公钥未正确添加或私钥路径不对查看~/.ssh文件检查密钥并重新配置多账户串号凭据管理器记住了旧用户查看系统凭据列表清理凭据或用 SSH config远程地址显示错误insteadOf反向规则执行 grep 检查配置删除反向规则6. 从实际操作中总结的几条经验这套报错我前前后后处理过很多次现在基本形成了自己的固定动作。新机器拿来我会优先配 SSH 密钥因为长期来看是最省心的。如果只是临时给某个自动化任务提供一个 token我会选择生成一个短有效期、最小权限的令牌并且在任务脚本里用环境变量引用而不是把令牌明文写进命令。最后一次和特别提醒如果你身边的朋友也遇到Password authentication is not supported先帮他确认远程地址写在配置里到底长什么样然后再谈要不要生成令牌。很多人在这一步就已经跑偏了一直在重复检查密码本身却忽略了服务端已经关闭了密码认证这条通道。先看远程地址再选认证方式最后查权限整个排查过程其实用不了两分钟。