You need to enable JavaScript to run this app. 同localhost环境跨域名调用API出现SSL证书验证失败如何解决
优惠活动
大模型
产品
解决方案
定价
更多

同localhost环境跨域名调用API出现SSL证书验证失败如何解决

自签证书同服务器双站点OAuth请求SSL校验失败排查指南

已排除的非根因场景

通过现有现象可以直接排除以下方向,避免无效排查:

  • PHP OpenSSL全局环境异常:外网公开HTTPS端点请求正常,说明基础加密组件工作正常
  • Web服务SSL配置异常:浏览器可正常访问两个域名的HTTPS服务,说明站点证书的域名匹配、端口监听、证书文件加载都无问题
  • 业务代码逻辑异常:此前Docker独立部署环境下跨域调用正常,说明CI3、CI4的OAuth业务流程本身无bug
  • PHP OAuth扩展实现逻辑无关:用原生cURL直接请求domain_b接口也报完全相同的证书校验错误,说明问题是SSL链路配置不匹配,和扩展的业务封装无关

核心问题定位

从报错栈可以看出,所有错误都发生在PHP底层流的SSL握手环节,和两个常见的配置失效点直接相关:

  1. OAuth扩展的disableSSLChecks()方法作用范围有限:该方法仅对扩展内部封装的cURL请求逻辑生效,当getRequestToken()走PHP原生流包装器发起请求时,关闭SSL校验的配置不会传递到底层流的SSL上下文,导致校验逻辑仍然执行,这就是为什么方法调用了但没生效的原因。
  2. RHEL8的OpenSSL校验策略较严格:默认配置下会强制校验服务端证书的颁发者合法性、主机名匹配性,自签证书如果没有被加入客户端的信任CA列表,就会直接抛出certificate verify failed错误。此前Docker环境下请求正常,本质是容器内的OpenSSL默认校验策略更宽松,CA加载路径和当前宿主机不一致。

分步排查与解决操作

  1. 先验证domain_b服务端的证书链完整性
    执行命令直接和domain_b的443端口做SSL握手,定位具体校验失败的节点:
    openssl s_client -connect domain_b.tld:443 -servername domain_b.tld -CAfile /path/to/签发domain_b服务端证书的根CA.crt
    
    查看输出末尾的Verify return code:
    • 如果返回20、19类错误,说明CA文件路径不对,或者权限不足导致PHP进程无法读取
    • 如果返回0 (ok),说明CA文件本身正确,只是PHP的请求链路没有加载到这个CA
  2. 修复OAuth扩展配置不生效的问题
    不要仅依赖$conn->disableSSLChecks()方法,在发起OAuth请求前,直接给PHP全局流设置默认SSL上下文,绕过扩展的配置传递bug:
    // 开发环境临时使用,生产环境不建议关闭校验
    stream_context_set_default([
        'ssl' => [
            'verify_peer' => false,
            'verify_peer_name' => false,
            'allow_self_signed' => true
        ]
    ]);
    
    这个配置直接作用于PHP所有原生流请求的SSL层,不会因为扩展的实现缺陷导致配置失效。
  3. 修正CA配置之前不生效的问题
    此前用setCAPath()配置失败,通常是三个原因:
    • 传入的是domain_b的站点证书文件,而不是签发该站点证书的根CA文件
    • 证书文件的所有者/权限不对,php-fpm运行用户(apache/nginx)没有读权限,导致PHP无法加载CA
    • 配置路径的时候没有把CA加入系统信任库,导致OpenSSL找不到对应的证书
      可通过以下操作验证配置正确性:
    • 将domain_b的根CA文件复制到RHEL8的CA信任目录,执行更新命令:
      cp /path/to/domain_b根CA.crt /etc/pki/ca-trust/source/anchors/
      update-ca-trust extract
      
    • 直接执行curl https://domain_b.tld,如果不带-k参数能正常返回响应,说明CA配置正确,此时再发起OAuth请求就不会出现校验失败的问题
  4. 区分两类证书的校验逻辑,避免配置混淆
    当前报错是校验domain_b的服务端SSL证书失败,和两个站点各自独立的用户认证客户端CA体系完全无关,不需要把用户证书的CA加入对方的信任列表,只要信任对方的服务端根CA即可,避免冗余配置引入新的双向认证报错。

适配生产环境的兼容方案

开发环境打通请求后,按照生产环境的安全策略调整配置:

  • 不要在生产环境长期关闭SSL校验,而是通过将domain_b的服务端根CA加入domain_a所在服务的信任CA列表,实现严格证书校验的同时,保证跨域请求正常
  • 验证SELinux状态是否影响php-fpm读取CA证书文件:即使SELinux处于Permissive模式,也可以通过ls -Z命令查看CA文件的安全上下文是否和php-fpm进程的允许访问类型匹配,避免无日志的权限拦截。

内容的提问来源于stack exchange,提问作者ZombieShellback

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.27 07:45:05