Saltar al contenido

React-native fetch () del servidor https con certificado autofirmado

Solución:

Descargo de responsabilidad: esta solución debe ser temporal y estar documentada para que no permanezca en la fase de producción del software, esto es solo para desarrollo.

Para iOS, todo lo que tiene que hacer es abrir su xcodeproject (dentro de su carpeta iOS en RN) una vez que lo tenga abierto, vaya a RCTNetwork.xcodeproj y en ese proyecto, navegue a RCTHTTPRequestHandler.m

En ese archivo verá una línea como esta:

#pragma mark - NSURLSession delegate

justo después de esa línea, agregue esta función

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

Y listo, ahora puede realizar llamadas inseguras a su API sin un certificado válido.

Eso debería ser suficiente, pero si sigues teniendo problemas, es posible que debas ir al info.plist de tu proyecto, hacer clic izquierdo en él y elegir abrir como … código fuente.

y al final solo agrega

<key>NSAppTransportSecurity</key>
  <dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
  </dict>
  <key>NSExceptionDomains</key>
    <dict>
        <key>localhost</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
        <key>subdomain.example.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>

para que su archivo se vea así

    ...
    <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>
  <key>NSExceptionDomains</key>
    <dict>
        <key>localhost</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
        <key>subdomain.example.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>
</plist>

Para obtener una solución real lista para la producción, https://stackoverflow.com/a/36368360/5943130 esa solución es mejor

También me enfrento al mismo problema en Android. Finalmente encontré la solución para este problema.

import com.facebook.react.modules.network.OkHttpClientFactory;
import com.facebook.react.modules.network.OkHttpClientFactory;
import com.facebook.react.modules.network.OkHttpClientProvider;
import com.facebook.react.modules.network.ReactCookieJarContainer;

import java.security.cert.CertificateException;
import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.TimeUnit;


import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.CipherSuite;
import okhttp3.ConnectionSpec;
import okhttp3.OkHttpClient;
import okhttp3.TlsVersion;

import static android.content.ContentValues.TAG;

public class CustomClientFactory implements OkHttpClientFactory {
    private static final String TAG = "OkHttpClientFactory";
    @Override
    public OkHttpClient createNewNetworkModuleClient() {
        try {
            // Create a trust manager that does not validate certificate chains
            final TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return new java.security.cert.X509Certificate[]{};
                        }
                    }
            };

            // Install the all-trusting trust manager
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            // Create an ssl socket factory with our all-trusting manager
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();



            OkHttpClient.Builder builder = new OkHttpClient.Builder()
                    .connectTimeout(0, TimeUnit.MILLISECONDS).readTimeout(0, TimeUnit.MILLISECONDS)
                    .writeTimeout(0, TimeUnit.MILLISECONDS).cookieJar(new ReactCookieJarContainer());
            builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });

            OkHttpClient okHttpClient = builder.build();
            return okHttpClient;
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
            throw new RuntimeException(e);
        }
    }

}

y dentro de nuestra aplicación de Android MainApplication.java

 @Override
  public void onCreate() {
    super.onCreate();
    SoLoader.init(this, /* native exopackage */ false);  
    OkHttpClientProvider.setOkHttpClientFactory(new CustomClientFactory()); //add this line.
  }  

Es un trabajo para mi. Puede que ayude a todos.

Conseguí que esto funcionara en Android haciendo lo siguiente:

  1. Instale la CA en su dispositivo en Configuración -> Seguridad y ubicación> Avanzado> Cifrado y credenciales> Instalar desde almacenamiento. Puede confirmar que está instalado correctamente visitando el dominio a través de un navegador web en su dispositivo. Si el certificado se valida, entonces la CA está instalada.
  2. Cree una configuración de seguridad de red en res/xml/network_security_config.xml con los siguientes contenidos. Actualice los dominios.
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <!-- For React Native Hot-reloading system -->
        <!-- If you are running on a device insert your computer IP -->
        <domain includeSubdomains="true">localhost</domain>
        <domain includeSubdomains="true">your self signed domain</domain>

        <trust-anchors>
            <certificates src="https://foroayuda.es/system" />
            <certificates src="user" />
        </trust-anchors>
    </domain-config>

    <base-config cleartextTrafficPermitted="false" />
</network-security-config>
  1. Haga referencia a este archivo de configuración de su AndroidManifest.xml.
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application android:networkSecurityConfig="@xml/network_security_config"
                    ... >
        ...
    </application>
</manifest>
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *