React Native and self-signed certificates to call local development backend

Posted by ZedTuX 0n R00t on July 9, 2018

Here I’m explaining how to deal with the SSL issues due to self-signed certificates when you’re developing an app using React-Native, calling a backend application serving an API. An agnostic solution.

So let’s say you have a backend application, serving APIs, that you need to call from your React Native application, but this backend is 100% HTTPS, even in development mode.

When you’ll try first with fetch() but also with other libraries like axios, you’ll face an like that :

1
An SSL error has occurred and a secure connection to the server cannot be made.

Message is clear, you can’t just do that, you need to find workarounds.

The agnostic solution

The idea is to no try to use https:// procotol from the React Native app in the development environment, and build a small kind of SSL proxy in between, which will accepts incoming non HTTPS requests and forward them to our backend in HTTPS.

If you know me a bit, you’ll not I’m going with Docker whenever it is possible, and this is perfect case for Docker !

The backend app has a docker-compose.yml file where all the stuff is mounted (DB, tools and so on), and it’s the perfect place to install an Nginx instance, proxying the non HTTPS requests.

In the docker-compose.yml file, I have added the following section :

1
2
3
4
5
6
7
8
9
10
11
12
  ...
    # Proxy a non HTTPS request to an HTTP service (avoid self-signed certificate
    # issues).
  sslproxy:
    image: nginx
    links:
      - app
    ports:
      - "3080:3080"
    volumes:
      - ./.nginx-ssl-proxy:/etc/nginx/conf.d
  ...

Nothing fancy here, mounting an Nginx server, with some folders from the backend project (.ssl/ folder includes all the certificate files, .nginx-ssl-proxy/ contains the file we will see just now), listening on port 3080 and linked to the backend app, otherwise the forwarding will fail.

Be sure to mount the folder where are the certificate files (in my case .ssl/ mounted as /ssl/ in the container), and also create the folder .nginx-ssl-proxy/ and create a new file named proxy_ssl.conf with the following content :

1
2
3
4
5
6
server {
  listen 3080;
  location / {
     proxy_pass https://localhost:3000;
  }
}

Start this new service and you should be able to send requests to http://localhost:3080/api/....