React Native https 통신 오류

wony·2023년 11월 2일

React native로 채팅어플을 개발하던중 안드로이드에서만 https로의 통신이 되지 않았다

웹, ios, postman 모두 정상적으로 통신에 성공해 값을 넘겨 받았는데
오직 안드로이드에서만 안되니까 막막했다 이 문제 해결에 꽤 오랜 시간이 걸렸다
진짜 안본 블로그가 없을 정도로 간절했다

내가 해결한 방법을 적어보려고 한다

✏️ Server단에서 ssl 인증서를 추가해주기

내가 원인 분석을 하며 여러 자료를 찾아보니 제일 많이 나온 조언이 ssl인증서를 확인하라는 말이 제일 많았다
https://www.ssllabs.com/ssltest/index.html
위의 링크에서 확인해보고싶은 url을 입력하면 ssl의 보안상태를 진단해준다

이 부분은 나의 사수님께서 진행해주신 부분이다
이곳에서 weak라고 나온 부분을 수정해보거나 aws에서 dns caa 부분을 추가해주었다
그래도 동작하지 않았다

그래서 openssl에서 ssl인증서를 생성하고 추가해보기로했다
https://saysimple.tistory.com/62
이 블로그를 참고했고 그 뒤로 https로 통신이 가능해졌다

✏️ ssl ignore 추가해주기

useEffect안에서 get method로 값을 가져오는데 최초 1회는 값이 가져와지지만
그 다음부터는 Typeerror: network request failed 에러가 계속 되었다

많은 블로그들을 보다가 https://rubyfaby.medium.com/how-to-ignore-ssl-for-react-native-f808810ffaed
이 블로그의 내용을 참고하여 나의 프로젝트에도 추가했더니 그 뒤로 정상동작하게 되었다

1. /android/app/src/main/java/com/[yourapp]/ 위치에 IgnoreSSLFactory.java 파일을 만든다

(MainApplicaiton.java와 같은 위치에 만든다)

//IgnoreSSLFactory.java
package com.yourapp;  //이 자리는 본인의 package로 변경
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 android.util.Log;
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 IgnoreSSLFactory implements OkHttpClientFactory {
    private static final String TAG = "IgnoreSSLFactory";
    
    @Override
    public OkHttpClient createNewNetworkModuleClient() {
        try {
            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[]{};
                        }
                    }
            };
final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
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);
        }
    }
}

2. MainApplication.java 수정한다

  • import com.facebook.react.modules.network.OkHttpClientProvider; 추가한다

  • onCreate() 안에 OkHttpClientProvider.setOkHttpClientFactory(new IgnoreSSLFactory()); 추가한다

public void onCreate() {    
    super.onCreate();    
    SoLoader.init(this, /* native exopackage */ false);    
    OkHttpClientProvider.setOkHttpClientFactory(new IgnoreSSLFactory()); // 추가한 부분
    initializeFlipper(this,       
    getReactNativeHost().getReactInstanceManager());  
}

나와같이 안드로이드에서만 https통신이 안된다면 ssl인증서를 확인하고 그럼에도 안된다면
ssl ignore 파일을 추가해 보길 바란다

profile
무럭무럭 성장중🌿

0개의 댓글