curl 跟随同域 HTTP 到 HTTPS 跳转后认证头丢失
同一域名从 HTTP 80 跳到 HTTPS 443 仍会改变源,curl 默认不向新源转发认证头。核对逐跳请求并优先直连正式 HTTPS 接口,避免用全局凭据转发掩盖问题。
请求先返回 308,curl 跟随跳转后却收到 401 Unauthorized。详细日志里,第一跳有 Authorization,第二跳没有,并可能出现 Clear auth, redirects to port from 80 to 443。即使域名完全相同,HTTP 变为 HTTPS、端口从 80 变为 443,也会改变这次认证所对应的源。
当前 curl/libcurl 默认不会把 Authorization 继续发送到不同源。这里的变化包括主机名、协议或端口任意一项不同;不能只比较域名。此规则同时涉及客户端生成的认证头和手动添加的 Authorization 头。
对照每一跳,不把 401 直接当成密码错误
先从已有的受控诊断记录核对初始 URL、响应状态、Location 和后续请求。下面是一条典型的跳转链示意,不含实际凭据:
http://api.example.com/token
-> 308 Location: https://api.example.com/token
-> HTTPS 请求不再携带 Authorization
-> 401 Unauthorized
这是凭据转发边界发生变化。308 保留请求方法和正文,也不意味着认证头必须跟随;“第二跳还是 POST”不能证明它仍携带认证信息。
如果第二跳确实仍有认证头,或完全没有发生跳转,就不能用这个原因解释失败。应继续检查凭据、认证机制、目标权限及服务端接收情况。不要在没有确认头部变化前反复更换密码。
需要补充日志时,只对有权限的测试接口使用测试凭据。--verbose 及应用的详细日志可能包含认证信息、Cookie 和响应中的令牌,应保存在受控位置,分享前清理。不要为了制造这条日志再把真实凭据发给 HTTP 地址。
优先直接请求确认过的 HTTPS 接口
如果接口正式地址本来就是 HTTPS,并允许直接调用,将初始 URL 改为该地址,消除这次无必要的跳转。先向接口提供方确认路径、方法、认证方式和目标,而不是直接信任未知响应里的 Location。
下面仅用于已确认采用 Basic 认证、可安全查询的测试接口。用户名和地址为占位值:
curl --silent --show-error \
--user 'example-user' \
'https://api.example.com/test-auth'
只提供用户名时,curl 会提示输入密码,避免把密码直接写进命令。示例没有启用自动重定向;如果该 HTTPS 接口仍返回 3xx,应先查清新目标,再决定后续流程。实际接口若使用 Bearer 令牌或其他认证机制,保留它要求的认证方式,不能为套用示例改成 Basic。
对提交类接口,只调整已经确认的初始地址,保留原有媒体类型、正文和方法约定。先用不会产生业务副作用的测试数据验证,不应反复调用真实扣费、创建或令牌发放流程来排查。
HTTP 首跳发送过敏感凭据时,后续跳到 HTTPS 并不能保护此前那一跳。应按实际暴露范围检查日志和网络链路,并依照凭据管理流程处理失效或更换,而不是仅把 URL 改好就忽略此前的传输。
--location-trusted 会扩大凭据接收范围
curl 的 --location-trusted 可以在跟随跳转时向其他源发送凭据;libcurl 对应的 CURLOPT_UNRESTRICTED_AUTH 要配合 CURLOPT_FOLLOWLOCATION 使用。默认关闭这项放宽,正是为了避免凭据被跳转到其他接收方。
它不是仅允许“同域 HTTP 升级到 HTTPS”的开关。启用后,后续目标还可能继续跳转,凭据也可能发送给新的接收方。因此不应把它全局加到所有请求上,或当成 401 的通用修复。即使限制跳转次数和协议,仍不能替代对接收方身份与权限的核验。
若业务确实需要跨源认证,先确认所有目标均被授权接收同一份凭据,并限制跳转链;更可控的做法是由应用逐跳检查目标,再仅向批准的地址发送相应认证。不要依赖手工拼接一个自定义敏感头来绕过保护:除 Authorization 和显式 Cookie 等规定的头部之外,不能假定 libcurl 会替你拦住其他敏感字段。
升级 PHP 后出现时,核对实际 libcurl
PHP 版本和扩展实际使用的 libcurl 版本不是同一个版本号。发生行为变化时,在执行请求的那个 PHP 运行环境里查看 curl_version() 返回的 version;另一个终端中 curl --version 的结果不能单独证明 PHP 使用同一套库。
旧环境曾继续发送凭据,也不能作为恢复旧行为的理由。当前安全边界应以实际库版本及其文档为准,不要为了让认证头再次跨源发送而降级库。
修复后,对照测试记录确认初始地址正确、认证只发送给批准的接收方、请求方法和数据仍符合接口要求,最终返回预期业务响应。若修改了自动跟随或凭据转发策略,保留原配置与修改范围;出现意外目标时,先撤销新增的转发放宽或停用自动跟随,再核查已发送的数据。撤回选项只影响后续请求,不能收回已经传出的凭据。


