본문 바로가기
React Native

React Native 에서 웹 브라우저 Redirection 하기

by 박주봉 2020. 5. 14.

expo WebBrowser

expo 의 with-webbrowser-redirect 번역결과

웹 사이트에서 앱으로 정보를 다시 전달하기 위해 iOS의 SFSafariViewController 및 SFAuthenticationSession 및 Android의 Chrome 인증 탭에서 제공하는 WebBrowser 모듈을 사용하는 것이 일반적입니다. 웹 브라우저 인증 세션을 사용하는 경우 쿠키가 Safari 및 Chrome과 쿠키를 각각 공유하므로 웹 브라우저에 이미 로그인 한 사이트도 브라우저에서 인증되기 때문에 일반적인 사용 사례는 인증입니다. 또한 개발자가 코드를 삽입 할 수 없으므로 WebView보다 안전합니다. 인증을 위해 WebView를 사용하는 경우 Apple은 앱을 거부합니다. SFSafariAuthenticationSession (WebBrowser.openAuthSessionAsync)을 사용해야합니다. WebBrowser에서 데이터를 다시 가져 오려면 웹 사이트에서 명시 적으로 앱으로 리디렉션하고 URL에 데이터를 제공해야합니다.

간단하게 말해 WebView보다 안전하게 웹 사이트에서 앱으로 Redirection 할 수 있는 모듈이라고 볼 수 있습니다.

설치

expo install expo-linking
expo install expo-web-browser
expo install expo-constants

RN 코드

import React from 'react';
import { Button, StyleSheet, Text, View } from 'react-native';
import { Linking } from 'expo';
import * as WebBrowser from 'expo-web-browser';
import Constants from 'expo-constants';

export default class App extends React.Component {
  state = {
    redirectData: null,
  };

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.header}>Redirect Example</Text>

        <Button
          onPress={this._openBrowserAsync}
          title="openBrowserAsync 리다이렉트 테스트"
        />
        {this._maybeRenderRedirectData()}
      </View>
    );
  }

  // redirect 후 실행
  _handleRedirect = event => {
    if (Constants.platform.ios) {
      WebBrowser.dismissBrowser();
    } else {
      this._removeLinkingListener();
    }

    // event 에 등록된 redirect url 값
    let data = Linking.parse(event.url);
    
    console.log(data);
    this.setState({ redirectData: data });
  };

  _openBrowserAsync = async () => {
    try {
      // addEventListener 등록
      this._addLinkingListener();
      let result = await WebBrowser.openBrowserAsync(
        // backend 주소와 redirection받을 url주소 셋팅
        `http://localhost:8080/test?linkingUri=${Linking.makeUrl('/?')}`
      );

      // https://github.com/expo/expo/issues/5555
      if (Constants.platform.ios) {
        this._removeLinkingListener();
      }
      this.setState({ result });
    } catch (error) {
      alert(error);
      console.log(error);
    }
  };

  _addLinkingListener = () => {
    Linking.addEventListener('url', this._handleRedirect);
  };

  _removeLinkingListener = () => {
    Linking.removeEventListener('url', this._handleRedirect);
  };

  _maybeRenderRedirectData = () => {
    if (!this.state.redirectData) {
      return;
    }

    return (
      <Text style={{ marginTop: 30 }}>
        {JSON.stringify(this.state.redirectData)}
      </Text>
    );
  };
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
    paddingBottom: 40,
  },
  header: {
    fontSize: 25,
    marginBottom: 25,
  },
});

안드로이드 앱에서 웹 브라우저 localhost 를 접근하려면 아래의 명령어를 입력하면 된다.

adb reverse tcp:8080 tcp:8080  ex) backend 포트번호가 8080 일 경우

테스트용 Spring boot backend 코드

package com.expo-web-browser.test.web;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class IndexController {

    @GetMapping("/test")
    public String test(Model model, @RequestParam(value = "linkingUri") String linkingUri) {
        linkingUri += "token=fakeToken";
        return "redirect:" + linkingUri;
    }
 }

실행 결과

테스트 전 (왼쪽) 테스트 후 (오른쪽)

 

테스트 결과 값

참고사항

ios 사파리 브라우저에서는 openAuthSessionAsync 메소드를 사용하여 테스트 할 수 있습니다.

참고자료

'React Native' 카테고리의 다른 글

리액트 네이티브로 앱 만들기  (1) 2020.05.11

댓글