리액트 네이티브 카카오 로그인 라이브러리를 사용하려면 sdk가 필요한데
내가 개발하고 있는 Expo 환경에서는 이 방식이 불가능하다.
대신 webview 라이브러리를 사용해서 소셜 로그인 구현이 가능하다.
📌React-native-webview
npm install react-native-webview //웹뷰 설치
리액트 네이티브 웹뷰는 말 그대로 web 화면을 띄우는 데 사용하는 라이브러리이다.
웹뷰를 사용해서 소셜 로그인을 구현할 때에는 웹 개발 시 REST API로 동작했던 방식 그대로 리액트 네이티브에 적용해 주면 된다. 나는 이번 프로젝트에서 카카오 / 네이버 / 깃허브 로그인을 사용하기로 했다.
1. 카카오 앱키 발급
카카오 개발자 센터에서 애플리케이션을 등록하고 이중 REST API 키를 사용해 주면 된다.
카카오 로그인을 활성화하고 리다이렉트 URI도 설정해 준다.
2. 네이버 클라이언트 키 발급
네이버 로그인도 마찬가지로 네이버 개발자센터에 애플리케이션을 등록하고 Client 아이디와 비밀번호를 가져와서 쓰면 된다.
3. 깃허브 Github 소셜 로그인 구현 ⭐⭐⭐
OAuth 방식 중 깃허브 로그인은 처음 도전해봤는데 방식은 동일했다.
1. 사용자가 Github에 로그인이 되어 있지 않은 경우 로그인 요청
2. AccessToken 발급을 위한 Code 값을 담아오기 위해 https://github.com/login/oauth/authorize로 요청
3. Code를 파라미터로 넘겨 AccessToken 발급 요청
4. Github를 통해 로그인한 사용자의 정보를 얻기 위해 AccessToken을 Authorization HTTP Header에 첨부하여 https://api.github.com/user에 요청
3-1. 깃허브 접속 후 Settings - Developer Settings 에서 App을 등록해 준다.
3-2. 자신의 프로젝트에 맞게 정보 입력
3-3. Client ID, Client secrets 저장해두고 가져와서 사용
앱키 발급을 마치고 이렇게 OAuth.js 파일을 생성해서 소셜 로그인에 관한 키들을 저장해 두었다.
export const kakaoClientId = '카카오 client id';
export const kakaoRedirectURL = '카카오 redirect url';
export const githubClientId = '깃허브 client id';
export const githubSecret = '깃허브 client secret';
export const githubRedirectURL = '깃허브 redirect url';
export const naverClientId = '네이버 client id';
export const naverRedirectURL = '네이버 redirect url';
export const naverSecret = '네이버 client secret';
export const NAVER_AUTH_URL = `https://nid.naver.com/oauth2.0/authorize?response_type=code&client_id=${naverClientId}&state=STATE_STRING&redirect_uri=${naverRedirectURL}`;
export const KAKAO_AUTH_URL = `https://kauth.kakao.com/oauth/authorize?client_id=${kakaoClientId}&redirect_uri=${kakaoRedirectURL}&response_type=code&prompt=login`;
export const KAKAO_ALL_LOGOUT_URL = `https://kauth.kakao.com/oauth/logout?client_id=${kakaoClientId}&logout_redirect_uri=${kakaoRedirectURL}`;
export const KAKAO_LOGOUT_URL = `https://kauth.kakao.com/oauth/logout?client_id=${kakaoClientId}&logout_redirect_uri=${kakaoRedirectURL}`;
export const GITHUB_AUTH_URL = `https://github.com/login/oauth/authorize?client_id=${githubClientId}&scope=study:status study:mogakko user:email&redirect_uri=${githubRedirectURL}`;
4. 인증 상태에 따라 화면을 분기처리 하기 위해 AuthStack.js 작성
대충 이런 식으로 Index.js 코드를 작성하고
import React, {useEffect, useState} from "react";
import { Text, View } from "react-native";
import { NavigationContainer } from "@react-navigation/native";
import AuthStack from './AuthStack';
import * as Font from 'expo-font';
const Navigation = () => {
const [fontLoad, setFontLoad] = useState(false)
//font 불러오기
return(
fontLoad?
<NavigationContainer>
<AuthStack />
</NavigationContainer>
:
<View>
<Text>Loading...</Text>
</View>
);
};
export default Navigation;
AuthStack.js 에서 각 화면을 나열한다.
import React, {useContext} from "react";
import { ThemeContext } from "styled-components";
import {createNativeStackNavigator} from '@react-navigation/native-stack';
//각 페이지
import LoginScreen from '../screens/auth/LoginScreen';
import KakaoLoginScreen from '../screens/auth/KakaoLoginScreen';
import NaverLoginScreen from "../screens/auth/NaverLoginScreen";
import GithubLoginScreen from "../screens/auth/GithubLoginScreen";
import SignupScreen from "../screens/auth/SignupScreen";
const Stack = createNativeStackNavigator();
// const screenOptions = {
// headerShown: false,
// };
const AuthStack = () => {
const theme = useContext(ThemeContext);
return(
<Stack.Navigator
screenOptions={{
headerShown: false,
headerTitleAlign: 'center',
//cardStyle: {backgroundColor: theme.backgroundColor},
}}
>
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="KakaoLoginScreen" component={KakaoLoginScreen} />
<Stack.Screen name="NaverLoginScreen" component={NaverLoginScreen} />
<Stack.Screen name="GithubLoginScreen" component={GithubLoginScreen} />
</Stack.Navigator>
);
};
5. 웹뷰 화면 띄우기
이제 대망의 웹뷰 화면 띄우기!! ⭐
View 대신 WebView로 감싸주고 그 안에 어떤 화면을 띄울지 적어주면 된다.
- source : Webview로 보여줄 페이지의 주소
- onMessage : Webview에서 함수가 호출될 때 실행되는 이벤트 함수
const INJECTED_JAVASCRIPT = `window.ReactNativeWebView.postMessage('message from webView')`;
const KakaoLoginScreen = ({navigation}) => {
return (
<ScreenContainer style={{flex: 1}}>
<WebView
originWhitelist={['*']}
scalesPageToFit={true}
source={{
uri: KAKAO_AUTH_URL
}}
javaScriptEnabled={true}
injectedJavaScript={INJECTED_JAVASCRIPT}
onMessage={ (event) => {
//LogInProgress(event.nativeEvent["url"]);
const data = event.nativeEvent.url;
getCode(data);
//onMessage... : webView에서 온 데이터를 event handler로 잡아서 logInProgress로 전달
}}
//onNavigationStateChange={onNavigationStateChange}
/>
</ScreenContainer>
);
}
export default KakaoLoginScreen;
const INJECTED_JAVASCRIPT = `window.ReactNativeWebView.postMessage('message from webView')`;
const GithubLoginScreen = () => {
return (
<ScreenContainer style={{flex: 1}}>
<WebView
originWhitelist={['*']}
scalesPageToFit={true}
source={{uri: GITHUB_AUTH_URL}}
javaScriptEnabled={true}
injectedJavaScript={INJECTED_JAVASCRIPT}
onMessage={
async(event) => {
navigation.navigate('Main')
}}
/>
</ScreenContainer>
)
}
export default GithubLoginScreen;
const INJECTED_JAVASCRIPT = `window.ReactNativeWebView.postMessage('message from webView')`;
const NaverLoginScreen = () => {
return (
<ScreenContainer style={{flex: 1}}>
<WebView
originWhitelist={['*']}
scalesPageToFit={true}
source={{uri: NAVER_AUTH_URL}}
javaScriptEnabled={true}
injectedJavaScript={INJECTED_JAVASCRIPT}
onMessage={
async(event) => {
navigation.navigate('Main')
}}
/>
</ScreenContainer>
)
}
export default NaverLoginScreen;
6. 실행 화면
아직 부끄러운 화면이지만...암튼 버튼은 이렇게 만들었고
각각의 소셜 로그인 버튼을 클릭했을 때 웹뷰로 화면 띄우기까지 성공했다!