💻 my code archive/✨React-Native

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

얼레벌레 개발자👩‍💻 2022. 10. 5. 16:29
반응형

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

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

 

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

반응형