You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native Expo集成VPN时遇UNABLE TO VERIFY LEAF SIGNASTURE错误求助

解决Expo React Native VPN环境下的SSL证书验证错误(unable to verify leaf signature)

这个错误本质是VPN环境下设备无法获取完整的SSL证书链(浏览器会自动补全中间证书,但React Native/Expo不会),以下是几个可行的解决方案,按安全性和生产可用性排序:

方案1:导入完整证书链(安全,生产可用)

步骤1:导出目标域名的完整证书链

用openssl命令导出包含根证书、中间证书的完整链:

openssl s_client -connect your-domain.com:443 -showcerts </dev/null 2>/dev/null | openssl x509 -outform PEM > full-chain.pem

也可以直接在浏览器中导出网站的所有证书,合并成一个.pem文件。

步骤2:将证书加入Expo项目

把full-chain.pem放到项目的assets/certs目录,修改app.json确保证书被打包:

{
  "expo": {
    "assetBundlePatterns": [
      "**/*",
      "assets/certs/**/*"
    ]
  }
}

步骤3:配置axios使用证书验证

用expo-file-system读取证书内容,创建带可信证书的axios实例:

import axios from 'axios';
import * as FileSystem from 'expo-file-system';
import { Platform } from 'react-native';

// 读取打包后的证书文件
const getCertContent = async () => {
  const certAsset = FileSystem.bundledAssets.find(asset => asset.endsWith('full-chain.pem'));
  const certPath = `${FileSystem.documentDirectory}${certAsset}`;
  return await FileSystem.readAsStringAsync(certPath);
};

// 创建安全的axios实例
export const getSecureAxios = async () => {
  const certContent = await getCertContent();
  
  const agentConfig = { ca: certContent, rejectUnauthorized: true };
  
  return axios.create({
    // Android端用Node.js风格的https agent
    httpsAgent: Platform.OS === 'android' ? new (require('https').Agent)(agentConfig) : undefined,
    // iOS端可通过ATS补充配置,或结合EAS构建使用SSL固定库
  });
};

方案2:EAS构建+SSL固定库(最安全,生产推荐)

如果你的项目使用EAS构建(而非Expo Go),可以用react-native-ssl-pinning库实现严格的SSL固定:

  1. 安装依赖:
npm install react-native-ssl-pinning
  1. 配置axios使用该库的adapter:
import axios from 'axios';
import { SSLPinning } from 'react-native-ssl-pinning';

const secureAxios = axios.create({
  adapter: async (config) => {
    const response = await SSLPinning.fetch(config.url, {
      method: config.method,
      headers: config.headers,
      body: config.data,
      sslPinning: {
        certs: ['full-chain'], // 对应assets中证书文件名(不含.pem)
      },
    });

    return {
      data: response.data,
      status: response.status,
      statusText: response.statusText,
      headers: response.headers,
      config: config,
    };
  },
});

方案3:临时禁用SSL验证(仅测试用,不安全)

如果只是临时测试,可以通过自定义axios adapter绕过验证,绝对不能用于生产:

import axios from 'axios';
import { Platform } from 'react-native';

const insecureAxios = axios.create({
  adapter: async (config) => {
    const fetchOptions = {
      method: config.method,
      headers: config.headers,
      body: config.data,
      ...(Platform.OS === 'android' ? { rejectUnauthorized: false } : {}),
    };

    const response = await fetch(config.url, fetchOptions);
    const data = await response.text();

    return {
      data,
      status: response.status,
      statusText: response.statusText,
      headers: response.headers,
      config,
    };
  },
});

为什么之前的方法失效?

  • Node.js https库:Expo基于React Native,不支持Node核心模块,无法直接使用。
  • RN-nodify:该工具是为纯React Native项目适配Node模块的,Expo架构不兼容。
  • process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0':这个环境变量只在Node.js环境生效,React Native用的是JSC/Hermes引擎,不遵循Node的环境变量规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 00:44:55