RN Webview에 localhost띄우기

이진경·2024년 10월 25일
0

React native

목록 보기
3/4

보통 웹을 RN으로 말아서 앱으로 만들경우, 해당 webView에 설정된 uri의 인증서 이슈가 조금이라도 있으면 해당 Url로 절대 들여보내주지 않는다.
그렇지만 웹은 신뢰할 수 없는 페이지 입니다 ! 라고 하면서 들여는 보내주는걸 간간히 봤을것이다.

당연한거 아닌가? 라고 생각할지 모르겠지만 !!
개발자들은 당연한게 아니다 !! 왜냐면 RN통신부를 작업할때는 RN에 로컬호스트를 띄워야 좀더 편한 테스트가 가능하기 때문이다.

일단 필자의 개발 환경이다.
웹뷰: jsp, os: macos, simulator: iphone 16 pro

차근차근 실행했던 단계별로 나열해보도록 하겠다.
1. http를 https 로 바꿔주기
이것은 말그대로 로컬환경의 인증서를 만들어서 해당 인증서를 가지고 로컬실행을 하는것이다.

  • mkcert, nss 깔기

    $ brew install mkcert
    $ brew install nss

brew가 없다면 깔아주도록 하자.

  • mkcert 환경 등록해주기

    $sudo mkcert -install

  • 인증서 발급받기
    Java에서는 PKCS 형식의 인증키, 공개키가 하나로 묶인 형식을 이용하기때문에 .p12로 생성

    $ mkcert -pkcs12 -p12-file keystore.p12 localhost 127.0.0.1 "*.myexample.domain"

이렇게 하면

이런식으로 만들어졌다고 뜨고 기본 password는 'changeit'이다.

  • 해당 인증서를 프로젝트에 추가하기
    필자의 프로젝트는 springboot/jsp 형태였어서 myapp-local.yml 파일에 추가해주었다.
    추가 예시
server:
  ssl:
    enabled: true
    key-store: ${user.home}/keystore.p12
    key-store-type: PKCS12
    key-store-password: changeit
  • app코드에 uri셋팅하기
<WebView
    source={'https://myip:8083'}
/>

ip는 public ip 로 집어넣기
wifi 설정 > 현재 연결된 wifi 세부사항에 들어가면 현재 public ip를 알수있다.

그렇게 하면 일단 오류메시지만 덩그러니 있는 페이지가 뜬다.

  • node_module/react-native-webview 다이렉트로 수정해버리기
    저거는 인증서가 유효하지 않다 라는것이고..
    나는 단지.. 로컬로 띄워서 RN메시징을 테스트 해보고싶었을 뿐이고...
    로컬환경에서 인증서도 만들었고....
    흑흑흑흑 그냥 무시 해주면 안돼 ??? 외않되?

그래서 아예 ssl유효 인증을 구분하는 코드를 바꿔버렸다. ㅎㅎ
react-native-webview 라이브러리는 버전마다 코드가 바뀔수도 있으니
필자가 수정한것을 토대로 코드를 찾아서 직접 수정하길 바란다.. ! 굳럭 ㅠ

  • RNCWebViewImpl.m 파일 수정하기
    didFailProvisionalNavigation를 전체검색해서 그안의 내부를 다 주석처리 해버리자.
    이 코드들은 에러가 나타나면 화면에 흰화면+에러로그를 출력해주는 코드들이다.

didReceiveAuthenticationChallenge를 전체검색해서 내부를 바꾸자

if ([[challenge protectionSpace] serverTrust] != nil && customCertificatesForHost != nil && host != nil) {
...
if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodHTTPBasic) {
...

저 위의 두개의 if문을 전체 주석처리 해버리자. 그리고 아래의 코드를 집어넣기

// 모든 서버 인증서를 신뢰하도록 설정
  if ([[challenge protectionSpace] serverTrust] != nil) {
    SecTrustRef trust = [[challenge protectionSpace] serverTrust];
    NSURLCredential *credential = [NSURLCredential credentialForTrust:trust];
    completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
    return;
  }

  // 기본 인증 처리 (HTTP Basic)
  if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodHTTPBasic) {
    NSString *username = [_basicAuthCredential valueForKey:@"username"];
    NSString *password = [_basicAuthCredential valueForKey:@"password"];
    if (username && password) {
      NSURLCredential *credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistenceNone];
      completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
      return;
    }
  }

그러고 빌드하면 화면이 잘 나온다....

profile
기록남기기

0개의 댓글