Réagir indigènes fetch() du serveur https avec certificat auto-signé

j'essaie de communiquer avec le serveur https ayant un certificat auto-signé.

je peux le faire à partir de L'application.Net (en utilisant ServicePointManager.L'événement ServerCertificateValidationCallback), de l'application native iOs (en utilisant allowsAnyHTTPSCertificateForHost) ou du navigateur web (il suffit de déclarer que le certificat est fiable).

mais je ne peux pas le faire fonctionner dans l'application react-native (ni dans Android ni dans le simulateur iOS).

j'ai essayé différentes choses, mais toujours pas réussir.

je sais qu'il y a certains sujets similaires:

ignorer les erreurs pour les certificats SSL auto-signés en utilisant l'API fetch dans une application Réactnative?

React Native XMLHttpRequest request échoue si le certificat ssl (https) n'est pas valide

Fetch dans réagissent natif habitude de travailler avec ssl sur android

Problèmes de l'extraction de données à partir d'un SSL fonction Le serveur

impossible de faire des appels API en utilisant react-native

mais ils ne contiennent pas de réponses ou ne fonctionnent pas (et ils ne couvrent pas la programmation android du tout). Recherche d'autres ressources n'a pas été productive.

je crois qu'il devrait être un moyen facile de travailler avec certificat auto-signé. Suis-je tort? Est-ce que quelqu'un le sait (à la fois pour iOS et Androïde)?

18
demandé sur Community 2016-03-29 18:50:48

2 réponses

Disclaimer: Cette solution doit être temporaire et documentée afin de ne pas rester dans la phase de production du logiciel, c'est pour le développement seulement.

pour iOS, Tout ce que vous avez à faire est d'ouvrir votre xcodeproject (à l'intérieur de votre dossier iOS dans RN) une fois que vous l'avez ouvert, allez sur RCTNetwork.xcodeproj et dans ce projet, naviguez vers RCTHTTPRequestHandler.m

Dans ce fichier, vous verrez une ligne comme ceci:

#pragma mark - NSURLSession delegate

juste après cette ligne, ajoutez ceci la fonction

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

et voilà, vous pouvez maintenant faire des appels non sécurisés vers votre API sans certificat valide.

cela devrait suffire, mais si vous avez encore des problèmes, vous pourriez avoir besoin d'aller à l'info de votre projet.plist, faites un clic gauche dessus et choisissez ouvrir... le code source.

et à la fin ajouter

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

ainsi votre fichier ressemblera à ceci

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

pour une véritable solution prête à la production, https://stackoverflow.com/a/36368360/5943130 cette solution est mieux

23
répondu Santiago Jimenez Wilson 2017-05-23 12:02:41

Piggybacking de la réponse de @Santiago Jimenez Wilson ici.

évidemment Patcher react-native lui-même est assez sale donc nous avons pris le contrôleur suggéré et l'avons extrait dans une catégorie.

il suffit de créer un nouveau fichier appelé RCTHTTPRequestHandler+yourPatchName.m quelque part dans votre projet:

//
//  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
1
répondu Philip Paetz 2017-01-17 17:49:19