React Native https 통신 오류

wony·2023년 11월 2일
0

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개의 댓글