如何基于React Native与Apollo Client实现iOS/Android移动端mTLS?
React Native + Apollo Client 实现 mTLS 认证方案
核心思路
Apollo Client 的 HTTP 链接支持自定义 fetch 函数,我们可以通过扩展这个函数,在请求中注入 mTLS 所需的客户端证书,以此实现双向 TLS 认证。
步骤1:准备并读取客户端证书
- 将你的客户端证书(通常是
.p12或.pem格式)放入 React Native 项目的assets目录,同时在metro.config.js中配置允许加载该类型文件。 - 使用
react-native-fs或内置的require读取证书文件的二进制内容(.p12格式需提前准备好证书密码)。
示例读取证书代码:
import RNFS from 'react-native-fs'; // 读取p12证书文件 const certPath = RNFS.MainBundlePath + '/certificates/client.p12'; const certData = await RNFS.readFile(certPath, 'base64');
步骤2:自定义支持mTLS的Fetch函数
React Native 原生 fetch 不直接支持 mTLS,可通过第三方库封装兼容的请求函数,注入证书配置:
基于 react-native-fetch-blob 实现
import RNFetchBlob from 'react-native-fetch-blob'; const mtlsFetch = async (uri, options) => { const response = await RNFetchBlob.fetch( options.method, uri, options.headers, options.body, { trusty: true, // 信任自签名证书(服务端用自签证书时开启) p12: certData, // 读取到的base64格式证书 p12Password: 'your-cert-password', // 证书密码(如有) } ); // 转换为Apollo Client兼容的Response格式 return new Response(response.data, { status: response.info().status, headers: response.info().headers, }); };
基于 axios + react-native-ssl-pinning 实现
import axios from 'axios'; import { SSLPinning } from 'react-native-ssl-pinning'; const mtlsFetch = async (uri, options) => { const sslPinning = new SSLPinning(); await sslPinning.initializePinning({ certs: ['client.pem'], // assets目录下的证书文件名 validateDomain: true, }); const response = await axios({ url: uri, method: options.method, headers: options.headers, data: options.body, httpsAgent: sslPinning.getHttpsAgent(), }); return new Response(JSON.stringify(response.data), { status: response.status, headers: response.headers, }); };
步骤3:将自定义Fetch注入Apollo Client
创建 Apollo Client 实例时,通过 createHttpLink 指定自定义的 fetch 函数:
import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client'; import { setContext } from '@apollo/client/link/context'; // 创建带mTLS的HTTP链接 const httpLink = createHttpLink({ uri: 'https://your-graphql-api-endpoint', fetch: mtlsFetch, // 注入自定义mTLS请求函数 }); // 可选:添加额外请求头(如Auth Token) const authLink = setContext((_, { headers }) => { return { headers: { ...headers, authorization: `Bearer ${your-auth-token}`, }, }; }); // 组合链接并初始化Client const client = new ApolloClient({ link: authLink.concat(httpLink), cache: new InMemoryCache(), });
注意事项
- 证书打包:iOS需在Xcode中将证书添加到项目资源,Android需放在
android/app/src/main/assets目录,确保证书被正确打包进App。 - 自签证书:生产环境建议使用正规CA签发的证书,测试环境使用自签证书时需开启信任配置。
- 版本兼容:确保第三方库(如
react-native-fetch-blob、react-native-ssl-pinning)与当前React Native版本匹配。
内容的提问来源于stack exchange,提问作者Rakmo
相关产品推荐
相关产品推荐

