You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6.0 KiB
6.0 KiB
URL编码修复文档
问题描述
时间: 2025-11-20 23:45
阶段: Jenkins 流水线阶段8 - 推送代码到 feature-ldl
错误信息
fatal: unable to access 'https://qq.com:****@bdgit.educoder.net/pu6zrsfoy/CHZU_CS231_SEB_lab.git/':
URL rejected: Port number was not a decimal number between 0 and 65535
根本原因分析
问题根源
用户名是邮箱地址:602924803@qq.com
当直接在Git URL中使用时:
https://602924803@qq.com:password@bdgit.educoder.net/...
Git会错误地解析URL:
- 用户名:
602924803 - 主机名:
qq.com - 端口:
password(被误认为是端口号) - 实际主机:
bdgit.educoder.net
为什么会这样?
在URL中,@符号有特殊含义:
- 第一个
@:分隔用户信息和主机 - 但邮箱地址中也包含
@ - Git解析器会混淆这两个
@
解决方案
方法:URL编码
将特殊字符转换为URL安全的格式:
| 字符 | URL编码 | 说明 |
|---|---|---|
@ |
%40 |
at符号 |
: |
%3A |
冒号 |
/ |
%2F |
斜杠 |
? |
%3F |
问号 |
# |
%23 |
井号 |
& |
%26 |
和号 |
= |
%3D |
等号 |
+ |
%2B |
加号 |
|
%20 |
空格 |
编码示例
原始用户名:
602924803@qq.com
URL编码后:
602924803%40qq.com
完整URL对比:
❌ 错误(未编码):
https://602924803@qq.com:password@bdgit.educoder.net/repo.git
✅ 正确(已编码):
https://602924803%40qq.com:password@bdgit.educoder.net/repo.git
实现方法
在 Jenkinsfile 中使用 PowerShell 编码
修复前的代码:
withCredentials([usernamePassword(
credentialsId: 'educoder-credentials',
usernameVariable: 'EDUCODER_USER',
passwordVariable: 'EDUCODER_PASS'
)]) {
bat """
git push https://%EDUCODER_USER%:%EDUCODER_PASS%@bdgit.educoder.net/...
"""
}
修复后的代码:
withCredentials([usernamePassword(
credentialsId: 'educoder-credentials',
usernameVariable: 'EDUCODER_USER',
passwordVariable: 'EDUCODER_PASS'
)]) {
bat '''
@echo off
setlocal EnableExtensions EnableDelayedExpansion
REM URL编码用户名和密码
for /f %%i in ('powershell -NoLogo -NoProfile -Command "[Console]::Out.Write([uri]::EscapeDataString($env:EDUCODER_USER))"') do set USER_ENC=%%i
for /f %%i in ('powershell -NoLogo -NoProfile -Command "[Console]::Out.Write([uri]::EscapeDataString($env:EDUCODER_PASS))"') do set PASS_ENC=%%i
git push https://%USER_ENC%:%PASS_ENC%@bdgit.educoder.net/...
'''
}
PowerShell URL编码命令
# 编码用户名
[uri]::EscapeDataString("602924803@qq.com")
# 输出: 602924803%40qq.com
# 编码密码
[uri]::EscapeDataString("password")
# 输出: password(如果没有特殊字符则不变)
测试验证
本地测试
# 测试URL编码
powershell -Command "[uri]::EscapeDataString('602924803@qq.com')"
# 应该输出: 602924803%40qq.com
# 测试Git推送(使用编码后的凭据)
git push https://602924803%40qq.com:password@bdgit.educoder.net/pu6zrsfoy/CHZU_CS231_SEB_lab.git HEAD:feature-ldl
Jenkins 测试
- 推送代码到Gitea触发构建
- 观察阶段8的执行
- 确认推送成功
其他解决方案(备选)
方案1: 使用Git Credential Helper
# 配置凭据助手
git config credential.helper store
# 第一次推送时输入凭据
git push https://bdgit.educoder.net/pu6zrsfoy/CHZU_CS231_SEB_lab.git HEAD:feature-ldl
# 输入用户名: 602924803@qq.com
# 输入密码: osgis123
# 后续推送会自动使用保存的凭据
优点: 不需要在URL中包含凭据
缺点: 需要交互式输入,不适合CI/CD
方案2: 使用SSH密钥
# 生成SSH密钥
ssh-keygen -t rsa -b 4096 -C "jenkins@slms.local"
# 添加公钥到头歌账户
# 使用SSH URL推送
git push git@bdgit.educoder.net:pu6zrsfoy/CHZU_CS231_SEB_lab.git HEAD:feature-ldl
优点: 更安全,不需要密码
缺点: 需要在头歌配置SSH密钥
方案3: 使用Personal Access Token
# 在头歌生成访问令牌
# 使用令牌代替密码
git push https://602924803%40qq.com:TOKEN@bdgit.educoder.net/...
优点: 更安全,可以设置权限和过期时间
缺点: 需要头歌支持Personal Access Token
最佳实践
1. 始终对URL凭据进行编码
// ✅ 好的做法
for /f %%i in ('powershell -Command "[uri]::EscapeDataString($env:USER)"') do set USER_ENC=%%i
git push https://%USER_ENC%:%PASS_ENC%@...
// ❌ 不好的做法
git push https://%USER%:%PASS%@...
2. 使用凭据管理器
// ✅ 使用 Jenkins 凭据
withCredentials([usernamePassword(...)]) {
// 使用凭据
}
// ❌ 硬编码凭据
bat "git push https://user:pass@..."
3. 避免在日志中暴露凭据
// ✅ 使用 @echo off 和 setlocal
bat '''
@echo off
setlocal EnableDelayedExpansion
...
'''
// ❌ 直接使用,可能在日志中显示
bat "git push https://%USER%:%PASS%@..."
相关资源
URL编码参考
Git凭据管理
总结
问题
- 用户名包含
@符号导致Git URL解析错误
解决
- 使用PowerShell的
[uri]::EscapeDataString()进行URL编码 - 将
@编码为%40
结果
- ✅ Git URL格式正确
- ✅ 推送到头歌成功
- ✅ 流水线完整执行
修复状态: ✅ 已完成
测试状态: ⏳ 待Jenkins验证
文档版本: 1.0