Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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.

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.

like image 460
sgrove Avatar asked Oct 01 '15 16:10

sgrove


People also ask

Is it possible to ignore SSL verification for fetch API in react app?

No, this error is from your browser and cannot be avoided in JavaScript. You must either add the self-signed certificate to your root certificate repository on your local machine or obtain a valid signed certificate from a free service such as Let's Encrypt.

How do I add a self signed certificate to react app?

Navigate to the root folder of your React app and generate an SSL certificate. First, create a folder for the certificate. Run the following to generate the certificate and store it in the folder you just created.

How do you integrate SSL pinning in react native?

To properly implement SSL pinning, we need a trusted certificate from a server we are communicating with. We can get a certificate from a server by using openssl. And copy the mycert. cer file into your app's /android/app/src/main/assets/ directory.


2 Answers

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.

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.

  • 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 hosts file 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)

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!

like image 199
m59 Avatar answered Oct 08 '22 20:10

m59


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

In that file you will see a line like this:

 #pragma mark - NSURLSession delegate 

right after that line, add this function

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

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

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.

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/5943130 that solution is better

like image 38
Santiago Jimenez Wilson Avatar answered Oct 08 '22 21:10

Santiago Jimenez Wilson