There is no anchor tag in React Native, so we can't write <a href="https://expo.io">, instead we have to use Linking.openURL.
현재 우리 프로젝트의 개발 사양은 프론트 : 리액트 네이티브 , 백엔드 : 자바 스프링 으로 구성되어 있다.
구글 , 네이버 등 소셜 로그인을 Oauth 를 통해 구현하는 중에 생긴 어려움에 대해 해결한 과정을 쓰고자 한다!
크게 로그인의 로직은 다음과 같았다.
1. 앱에서 서버의 특정 url 로 웹을 연다.
2. 웹을 열게 되면 구글 로그인 화면이 나오게 된다.
3. 로그인이 정상적으로 완료되면 서버에서 JWT을 가지는 주소를 redirect 시켜준다.
4. 해당 url 에서 jwt 토큰을 가지고와 서버와 인증을 진행한다.
위의 과정에서 볼 수있듯이 서버와의 인증은 JWT 를 통해 인증하는 방식으로 구현하고자 했다.
이때 프론트에서 발생한 문제는 크게 두가지였다.
expo install expo-web-browser
1. 앱 내에서 다른 컴포넌트로 라우팅 시키는 것이 아닌 웹에서의 a 태그 기능을 하게 하는 것
2. 보낸 주소에서 리 다이렉팅 시키는 url 을 처리해야한다는 것
기본적으로 웹 프론트 서버에서는 url로 요청이 들어오는 것을 라우팅하여 처리할수 있다. 하지만 앱 내에서 이것을 가능하게 하는 로직이 뭔지 몰랐고 expo 문서를 뒤져보며 다음과 같은 API -reference 를 발견할 수 있었다
Linking
There is no anchor tag in React Native, so we can't write , instead we have to use Linking.openURL.
리액트 네이티브에서는 a 태그가 없기 때문에 다른 방식으로 웹사이트를 호출한다. 간단한 사용예제에 대해서 알아보자.
import * as Linking from 'expo-linking';
Linking.openURL('https://expo.io');
앱 내에서 모달형식으로 url을 오픈하는 expo 에서 지원하는 라이브러리 expo-web-browser 가 있다.
Installation
expo install expo-web-browser
Usage
import React, { Component } from 'react';
import { Button, Linking, View, StyleSheet } from 'react-native';
import * as WebBrowser from 'expo-web-browser';
import Constants from 'expo-constants';
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<Button
title="Open URL with ReactNative.Linking"
onPress={this._handleOpenWithLinking}
style={styles.button}
/>
<Button
title="Open URL with Expo.WebBrowser"
onPress={this._handleOpenWithWebBrowser}
style={styles.button}
/>
</View>
);
}
_handleOpenWithLinking = () => {
Linking.openURL('https://expo.io');
};
_handleOpenWithWebBrowser = () => {
WebBrowser.openBrowserAsync('https://expo.io');
};
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
},
button: {
marginVertical: 10,
},
});
Linking 은 다른 웹사이트를 여는것 뿐만 아니라 다른 웹 또는 앱에서 나의 앱을 열수 있게 한다. 기본적으로 Expo Clinet 를 거쳐서 열게 된다. 내 앱과 링크 시키기 위해 먼저 app,json 에서 scheme 를 정의해줘야 한다.
{
"expo": {
"scheme": "myapp"
}
}
내가 호출한 url 을 통해 데이터를 받고자 한다면 Linking.makeUrl() 을 사용하면 된다. 안에 파라미터로 돌아올 주소를 설정하면 된다. 디폴트 값으로 개발시에는 exp://localhost:19000 의 주소가 설정 되어 있다. 파라미터를 전해줌으로서 리턴 url을 정해줄수 있다.
기본적으로 Linking.addEventLister('url',callback) 을 통해 이벤트 리스너를 등록하고 처리를 해주면 된다. 간단한 사용은 다음과 같다.
let redirectUrl = Linking.makeUrl('path/into/app', { hello: 'world', goodbye: 'now' });
처음 파라미터는 돌아올 주소이고 그다음은 쿼리 파람스 에 해당하는 내용이다. 돌아올때 주소는 다음과 같다. myapp:///path/into/app?hello=world&goodbye=now
다음문장이 의미하는 바는 너의 앱에 링크되었어! 주소 :path/into/app 으로 연결 data: {hello: 'world' , goodbye: 'now' } 과 같다.
Linking 을 authentication 을 위해 사용 할수 있다. 가장 많이 쓰게 되는 이유이다. 예를 들어 로그인을 위한 웹브라우저 세션을 열고 유저가 성공적으로 로그인을 했을 때 authentication token 을 가지고 나에게 URL을 보내게 된다.
실제로 많은 Oauth 를 지원하는 로그인에서 redirectUrl 을 적어야 하고 여기에 나의 Linking.makeUrl을 통해 만든 주소를 넣으면 성공적으로 토큰을 받을 수있다. 나의 서버에서 만든 JWT 토큰은 다음과 같은 형식으로 넘어오게 된다.
exp://127.0.0.1:19000?token=eyiOiJIUzUxMiJ9.eyxMSIsImlhdCI6MTU5NDk2NzM0MCwiZXhwIjoxNTk1ODMxMzQwfQ.W4Yyt2cxfTLvawYDwH9kut_JdEVxG0G2wvOQyHQfj2Kf3bIuPGpR99eG-KYQ