react native - para - React-native fetch() del servidor https con certificado autofirmado
react native fetch post example (4)
Conseguí esto trabajando en Android haciendo lo siguiente:
- Instale la CA en su dispositivo en Configuración -> Seguridad y ubicación> Avanzado> Cifrado y credenciales> Instalar desde el 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.
- Cree una configuración de seguridad de red en
res/xml/network_security_config.xml
con el siguiente contenido. Actualizar el dominio (s).
<?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="system" />
<certificates src="user" />
</trust-anchors>
</domain-config>
<base-config cleartextTrafficPermitted="false" />
</network-security-config>
- Consulte este archivo de configuración desde su
AndroidManifest.xml
.
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
<application android:networkSecurityConfig="@xml/network_security_config"
... >
...
</application>
</manifest>
Estoy tratando de comunicarme con el servidor https que tiene un certificado autofirmado.
Puedo hacer esto desde la aplicación .NET (usando el evento ServicePointManager.ServerCertificateValidationCallback), desde la aplicación nativa de iOs (utilizando permiteAnyHTTPSCertificateForHost) o desde el navegador web (solo debe declarar que el certificado es confiable).
Pero no puedo hacer que funcione en una aplicación nativa de reacción (ni en Android ni en el simulador de iOS).
He intentado cosas diferentes pero todavía no he tenido éxito.
Sé que hay algunos temas similares allí:
¿Ignora los errores de los certificados SSL autofirmados que utilizan la API fetch en una aplicación ReactNative?
La solicitud nativa de XMLHttpRequest falla si el certificado ssl (https) no es válido
Recuperar la respuesta nativa no funcionará con ssl en Android
Problemas para obtener datos de un servidor basado en SSL
No se pueden hacer llamadas a API usando react-native
Pero o bien no contienen respuestas o no funcionan (y no cubren la programación de Android en absoluto). Buscar otros recursos tampoco fue productivo.
Creo que debería haber una manera fácil de trabajar con un certificado autofirmado. ¿Me equivoco? ¿Alguien lo sabe (tanto para iOS como para Android)?
Descargo de responsabilidad: esta solución debe ser temporal y 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 haya abierto, vaya a RCTNetwork.xcodeproj y en ese proyecto, navegue hasta RCTHTTPRequestHandler.m
En ese archivo verás 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 hacer llamadas inseguras a su API sin un certificado válido.
Eso debería ser suficiente, pero si aún tiene problemas, puede que necesite ir a info.plist de su proyecto, hacer clic izquierdo en él y elegir abrir como ... código fuente.
y al final solo agregue
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
por lo que su archivo se verá 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>
</dict>
</plist>
Para una solución lista para producción real, https://.com/a/36368360/5943130 esa solución es mejor
Esto se debe a un certificado autofirmado que se usa para el cifrado. Debido a razones de seguridad en Android, exige la autoridad de CA firmada o certificados de confianza
Usa este plugin para evitar esto.
https://www.npmjs.com/package/react-native-fetch-blob
RNFetchBlob.config({
trusty : true
})
.then(''GET'', ''https://xxxxx.com'')
.then((resp) => {
// ...
})
Agregue config trusty como true para confiar en el certificado cuando POST o GET API''s
Piggybacking de la respuesta de @Santiago Jimenez Wilson aquí.
Obviamente, la aplicación de parches react-native en sí misma es bastante sucia, por lo que tomamos el reemplazo sugerido y lo extrajimos en una categoría.
Simplemente cree un nuevo archivo llamado RCTHTTPRequestHandler+yourPatchName.m
en algún lugar de su proyecto:
//
// RCTHTTPRequestHandler+yourPatchName
//
#import "RCTBridgeModule.h"
#import "RCTHTTPRequestHandler.h"
@implementation RCTHTTPRequestHandler(yourPatchName)
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{
completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
}
@end
El siguiente paso sería diferenciar entre dev y prod y solo sobrecargar el método para dev.