[RN 프로젝트] #2 Expo 환경 React native webview 카카오 네이버 깃허브 소셜 로그인 화면 띄우기
my code archive
article thumbnail
반응형

리액트 네이티브 카카오 로그인 라이브러리를 사용하려면 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. 실행 화면

아직 부끄러운 화면이지만...암튼 버튼은 이렇게 만들었고

 

각각의 소셜 로그인 버튼을 클릭했을 때 웹뷰로 화면 띄우기까지 성공했다!

반응형
profile

my code archive

@얼레벌레 개발자👩‍💻

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

반응형