【问题标题】:Ignore errors for self-signed SSL certs using the fetch API in a ReactNative App?在 ReactNative 应用程序中使用 fetch API 忽略自签名 SSL 证书的错误?
【发布时间】:2015-12-29 18:40:29
【问题描述】:

我正在构建一个小型 ReactNative iOS 应用程序。在其中,我使用 fetch API 向我控制的具有有效但自签名 SSL 证书的服务器发出简单的 get 请求。可以理解,这会导致错误。

在 iOS/JSC 之间,我不确定如何(或什么!)我可以为我的应用程序配置以忽略此错误 - 我目前找到的所有答案都与 Objective-C 解决方案有关,我正在寻找对于我可以在 JSC 环境中使用的东西。

【问题讨论】:

    标签: javascript ios ssl react-native


    【解决方案1】:

    我遇到了同样的问题。正如您所指出的,让原生 iOS 应用程序使用自签名证书的唯一方法似乎是编写/修改 Objective-C 代码,这对于使用 React Native 的 JavaScript 开发人员来说不是一个好方法。出于这个原因,我认为您的问题是X/Y problem,我建议使用与一开始使用自签名证书不同的方法来解决您的整体问题。

    我改为使用真正的证书进行开发。这是我为使本地开发 API 与 SSL 和 React Native 一起工作所做的工作。它免费且简单。

    • SSH 到与您的域关联的公共服务器
    • 安装letsencrypt
    • 为您的开发子域生成证书
      • dev.my-domain.com 用于在本地开发我的网站/webapp
      • api.dev.my-domain.com 用于 api
      • ./letsencrypt-auto certonly --standalone -d dev.my-domain.com -d api.dev.my-domain.com
    • 将 fullchain.pem 和 privkey.pem 复制到本地计算机
      • 可能在/etc/letsencrypt/live/dev.my-domain.com 下找到
      • 从远程计算机获取文件的一种方法:scp -r your_user@123.123.(...):/etc/letsencrypt/live/dev.my-domain.com ./
    • 用 fullchain.pem 和 privkey.pem 替换您的自签名证书
    • 将 dev.your-domain.com 和您使用的其他子域指向您的开发机器的 ip
      • 您可以在要使用域的每台计算机上修改您的 hosts 文件
      • 如果你的路由器有dnsmasq,你可以为整个网络做类似address=/dev.my-domain.com/192.168.(...)的事情(我推荐这个)

    此时,由于您正在为正在访问的域使用真实的、受信任的证书,因此您的 api 现在将在浏览器和开发中的设备上受到信任!

    【讨论】:

    • 注意,letsencrypt 不适用于不可公开访问的内部服务器(例如在 vagrant 环境中运行的服务器)。
    • @IanVS 是的,但只要您的域有公共服务器,这应该不是问题。我的指南指示在域指向的公共服务器上使用letsencrypt,然后将证书复制到开发机器。
    • 这在生产中有何不同?移动设备/客户端不需要什么特别的东西,对吧?
    • @ryanwebjackson 此解决方案假设您在开发过程中使用某种不同的域/ip/url,而不是指向您的实时生产服务器,因为在这种情况下,不会有 ssl 证书无论如何都需要开发。
    • @Max 我喜欢自动化它。我在生产服务器上运行一个 docker 服务来更新生产服务器的证书和开发证书,然后它 git 提交开发证书,因此它可以通过简单的git pull 供本地使用。
    【解决方案2】:

    免责声明:此解决方案应该是临时的并记录在案,以便它不会停留在软件的生产阶段,这仅用于开发。

    对于 iOS,您所要做的就是打开您的 xcodeproject(在 RN 中的 iOS 文件夹中),然后转到 RCTNetwork.xcodeproj 并在该项目中导航到 RCTHTTPRequestHandler.m

    在该文件中,您将看到如下一行:

     #pragma mark - NSURLSession delegate
    

    在那一行之后,添加这个函数

    #if DEBUG
    - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
    {
      completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
    }
    #endif
    

    瞧,您现在可以在没有有效证书的情况下对您的 API 进行不安全的调用。

    这应该足够了,但是如果您仍然遇到问题,您可能需要转到项目的 info.plist,左键单击它并选择打开为...源代码。

    最后添加

    <key>NSAppTransportSecurity</key>
      <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
      </dict>
    

    所以你的文件看起来像这样

        ...
        <key>UISupportedInterfaceOrientations</key>
        <array>
            <string>UIInterfaceOrientationPortrait</string>
            <string>UIInterfaceOrientationLandscapeLeft</string>
            <string>UIInterfaceOrientationLandscapeRight</string>
        </array>
        <key>UIViewControllerBasedStatusBarAppearance</key>
        <false/>
        <key>NSLocationWhenInUseUsageDescription</key>
        <string></string>
      <key>NSAppTransportSecurity</key>
      <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
      </dict>
    </dict>
    </plist>
    

    对于真正的生产就绪解决方案,https://stackoverflow.com/a/36368360/5943130 该解决方案更好

    【讨论】:

    • 除了危险的不安全之外,如果您的服务需要任何 HTTP 身份验证,它也会以奇怪的方式失败。如需更安全的解决方案(不必是临时的),请阅读 Apple 开发人员库中的 developer.apple.com/library/content/documentation/…
    • 我只是复制粘贴这个,因为你可能已经错过了 免责声明:这个解决方案应该是临时的并记录在案,这样它就不会停留在软件的生产阶段,这是为了仅限开发。
    • 根据我的经验,临时解决方案的问题在于它们往往最终会发货。这就是为什么我强调永远不要建议暂时这样做。不管怎样,至少,你的 sn-p 应该用#if DEBUG 包裹起来。 :-)
    • 我同意……我们的开发人员有时会忘记我们是多么健忘。想一想,你指出的是一些中肯的建议
    • 这是此答案中第一个示例的 git 补丁,它信任 react-native 请求的所有证书:gist.githubusercontent.com/aleclarson/…
    【解决方案3】:

    此答案适用于 Android。

    1. node_modules\react-native\ReactAndroid\src\main\java\com\facebook\react\modules\network 上找到 OkHttpClientProvider.java。

    2. 使用 NDK 编译 ReactAndroid

    【讨论】:

    • 编译 ReactAndroid 使用 NDK?你能解释一下吗
    • @Sujit 你不构建它,那么修改后的代码不能工作
    • 说明中似乎缺少关键步骤。找到 OkHttpClientProvider.java 文件后,如何处理它?
    猜你喜欢
    • 2011-01-16
    • 2016-10-01
    • 2012-06-08
    • 2012-08-17
    • 1970-01-01
    • 2016-05-11
    • 2018-09-09
    • 1970-01-01
    相关资源
    最近更新 更多