javascript 在 ReactNative 应用程序中使用 fetch API 忽略自签名 SSL 证书的错误?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32892161/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 15:52:50  来源:igfitidea点击:

Ignore errors for self-signed SSL certs using the fetch API in a ReactNative App?

javascriptiossslreact-native

提问by sgrove

I'm building a small ReactNative iOS application. In it, I use the fetch API to make a simple get request to a server I control that has a valid - but self-signed - SSL cert. Understandably, this causes an error.

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

Between iOS/JSC, I'm unsure how (or what!) I can configure for my app to ignore this error - all the answers I've found so far are related to Objective-C solutions, I'm looking for something I can use with a JSC environment.

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

回答by m59

I encountered this same issue. As you noted, it seems the only way to get a native iOS app to work with a self-signed certificate is by writing/modifying Objective-C code, which is not a good approach for a JavaScript developer using React Native. For this reason, I think your question is an X/Y problem, and I propose solving your overall problem with a different approach from using a self-signed certificate in the first place.

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

I use a real certificate for development instead. Here is what I did to get my local development API working with SSL and React Native. It's free and simple.

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

  • ssh into your public server that your domain is associated with
  • install letsencrypt
  • generate a certificate for your development subdomains
    • dev.my-domain.com for developing my website/webapp locally
    • api.dev.my-domain.com for the api
    • ./letsencrypt-auto certonly --standalone -d dev.my-domain.com -d api.dev.my-domain.com
  • copy fullchain.pem and privkey.pem to your local machine
    • probably found under /etc/letsencrypt/live/dev.my-domain.com
    • one way to get the files from your remote machine: scp -r [email protected].(...):/etc/letsencrypt/live/dev.my-domain.com ./
  • replace your self-signed certificate with fullchain.pem and privkey.pem
  • point dev.your-domain.com and other subdomains you use to your development machine's ip
    • you can modify your hostsfile on each machine you want to use the domain
    • if your router has dnsmasq, you can do something like address=/dev.my-domain.com/192.168.(...)for the whole network (I recommend this)
  • ssh 进入与您的域相关联的公共服务器
  • 安装letencrypt
  • 为您的开发子域生成证书
    • 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 [email protected].(...):/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.(...)为整个网络做一些类似的事情(我推荐这个)

At this point, because you are using a real, trusted certificate for the domain you're accessing, your api will now be trusted in browsers and on devices in development!

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

回答by Santiago Jimenez Wilson

Disclaimer: This solution should be temporary and documented so that it won't stay in the production phase of the software, this is for development only.

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

For iOS, all you have to do is, open your xcodeproject (inside your iOS folder in RN) once you have that open, go to RCTNetwork.xcodeproj and in that project, navigate to RCTHTTPRequestHandler.m

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

In that file you will see a line like this:

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

 #pragma mark - NSURLSession delegate

right after that line, add this function

在该行之后,添加此功能

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

And voila, you can now make insecure calls to your API without a valid certificate.

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

That should be enough, but if you are still having problems, you might need to go to your project's info.plist, left click on it and choose open as... source code.

这应该足够了,但是如果您仍然遇到问题,您可能需要转到项目的 info.plist,左键单击它并选择 open as... source code。

and at the end just add

最后添加

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

so your file will look like this

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

    ...
    <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>

For a real production ready solution, https://stackoverflow.com/a/36368360/5943130that solution is better

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

回答by markjoker

This answer work for Android.

此答案适用于 Android。

  1. find OkHttpClientProvider.java on node_modules\react-native\ReactAndroid\src\main\java\com\facebook\react\modules\network.

  2. compile ReactAndroid use NDK

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

  2. 编译 ReactAndroid 使用 NDK