[RN 프로젝트] #9 리액트네이티브 + 스프링부트(Spring Boot) + JWT 네이버 로그인 구현, 로그아웃
my code archive
article thumbnail
반응형

정처기 끝났으니까 다시 시작....

카카오랑 조금 다르기도 하고 버전 올라가면서

조금 수정된 부분이 있어서 겨우겨우 성공..

리액트는 많아도 리액트네이티브+스프링부트+네이버 로그인

참고 소스는 지인짜 찾기 힘들어서 겨우겨우 했다ㅠㅠ

 

1. ⭐️Frontend

1. 네이버 개발자센터 등록

설명 생략

 

2. 리액트네이티브 네이버 로그인 라이브러리 설치

npm install @react-native-seoul/naver-login --save
// RN version >= 0.6.0부터 Auto Linking 적용,
// ios 경우 추가적으로 Cocoapods 설치 필요
cd ios && pod install

 

https://github.com/crossplatformkorea/react-native-naver-login

 

GitHub - crossplatformkorea/react-native-naver-login: 리엑트 네이티브 네이버 로그인 라이브러리

리엑트 네이티브 네이버 로그인 라이브러리. Contribute to crossplatformkorea/react-native-naver-login development by creating an account on GitHub.

github.com

 

3. info.plist 작성

<key>CFBundleURLTypes</key>
<array>
	<dict>
		<key>CFBundleTypeRole</key>
		<string>Editor</string>
		<key>CFBundleURLName</key>
		<string>naver</string>
		<key>CFBundleURLSchemes</key>
		<array>
			<string>{{ CUSTOM URL SCHEME }}</string>
		</array>
	</dict>
	...
</array>

 

⭐️주의할 점은 네이버 로그인 이외에 소셜 로그인을 2개 이상 사용하는 경우 아래와 같이 작성.

 

4. AppDelegate.m 수정

#import <NaverThirdPartyLogin/NaverThirdPartyLoginConnection.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  /* 생략 */
  
  [[NaverThirdPartyLoginConnection getSharedInstance] setIsNaverAppOauthEnable:YES];
  [[NaverThirdPartyLoginConnection getSharedInstance] setIsInAppOauthEnable:YES];
  
  return YES;
}

- (BOOL)application:(UIApplication *)app
     openURL:(NSURL *)url
     options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
     
   // 카카오  
   if([RNKakaoLogins isKakaoTalkLoginUrl:url]) {
      return [RNKakaoLogins handleOpenUrl: url];
   }

   // 네이버
  if ([url.scheme isEqualToString:@"naverLogin"]) {
      return [[NaverThirdPartyLoginConnection getSharedInstance] application:app openURL:url options:options];
    }
 return NO;
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
  return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}

/// This method controls whether the `concurrentRoot`feature of React18 is turned on or off.
///
/// @see: https://reactjs.org/blog/2022/03/29/react-v18.html
/// @note: This requires to be rendering on Fabric (i.e. on the New Architecture).
/// @return: `true` if the `concurrentRoot` feature is enabled. Otherwise, it returns `false`.
- (BOOL)concurrentRootEnabled
{
  return true;
}

@end

 

5. 실행 코드

버튼 클릭

<Button opt={"naver"} text="네이버 아이디 로그인"  handlePress={signInWithNaver}/>

네이버 로그인 작동

// 네이버 로그인 라이브러리
import NaverLogin from '@react-native-seoul/naver-login';

const getNaverUserInfo = async accessToken => {
        const profileResult = await NaverLogin.getProfile(accessToken);
        return fetch(`${naverRedirectURL}`,{
            method: 'POST',
            body: JSON.stringify(profileResult),
            headers: {
                'Content-Type': 'application/json',
            }
        }).then(response => response.json())
          .then(responseJson=> {
            console.log('naver responseJson', responseJson);
            if (responseJson.status === 200) {
                AsyncStorage.setItem('user_email', responseJson.email);
                AsyncStorage.setItem('user_token', responseJson.token);
                AsyncStorage.setItem('user_name', responseJson.username);
                navigation.navigate();
            } else {
                console.log('이메일 혹은 패스워드를 확인해주세요.');
            }
          }).catch (error => {
            console.error(error);
          });
    }

    const signInWithNaver = async () => {
        const {successResponse, failureResponse} = await NaverLogin.login(naverKey);
        if (successResponse) {
            try {
                console.log(successResponse);
                getNaverUserInfo(successResponse.accessToken);
                setNaverToken(successResponse.accessToken);
                navigation.navigate('MainStack');
            
            } catch (error) {
                console.log(error);
            }
        } else {
            setFailureResponse(failureResponse);
        }
    }

 

2. ⭐️Backend

카카오 로그인 백엔드 로직 참고

https://mycodearchive.tistory.com/308

 

[RN 프로젝트] #8 리액트네이티브 + 스프링부트(Spring Boot) + JWT 카카오 소셜 로그인 구현

아무리 여러 번을 해봐도 로그인은 늘 어렵다.....ㅎㅎㅎ 그리고 아직 친해지지 못한 맥북 + 리액트 네이티브 환경에서 하려니 엄청난 에러를 겪고 겨우 성공한 카카오 로그인... 시작!! ⭐️Fronten

mycodearchive.tistory.com

 

3. 로그아웃 모달

앱에 보통 로그아웃 버튼은 마이 페이지에 있으므로 마이페이지 화면에 로그아웃 버튼 추가

 

ModalButton.js 모달 버튼 컴포넌트

export default function ModalButton({onPress, text, white, width, outline}) {

    const theme = useContext(ThemeContext);

    return (
        <Pressable
            onPress={() => onPress()}
            white={white}
            width={width}
            outline={outline}
        >
            <Text colors={white ? '#8879B0' : 'white'}>{text}</Text>
        </Pressable>
    )
}

 

LogoutModal.js 로그아웃 모달

// 소셜 로그인 라이브러리에서 제공하는 로그아웃 함수 사용
import NaverLogin from '@react-native-seoul/naver-login';
import { logout} from '@react-native-seoul/kakao-login';

export default function LogoutModal() {

    const {isModalOpen, closeModal} = useLogoutModal();
    const navigation = useNavigation();
    const [kakaoToken, setKakaoToken] = useState('');
    const [naverToken, setNaverToken] = React.useState(null);

    function logoutALL() {
        AsyncStorage.clear();
		//네이버 로그아웃
        signOutWithNaver();
		//카카오 로그아웃
        signOutWithKakao();
		//로그아웃 완료 시 로그인 화면으로 이동
        navigation.navigate('Login');
        
        closeModal();
    }

    const signOutWithKakao = async() => {
        try {
            const message = await logout();
            console.log(message);
            setKakaoToken('');
        }catch (err) {
            console.log('signOut error', err);
        }
    };

    const signOutWithNaver = async () => {
        await NaverLogin.logout();
        setNaverToken('');
    };

    return (
        <ModalSheet isModalOpen={isModalOpen} closeModal={closeModal}>
            <ModalContainer>
                <Text>로그아웃 하시겠어요?</Text>
                <Row>
                    <ModalButton
                        onPress={logoutALL}
                        text={'예'}
                        white
                        width={'110px'}
                        outline
                    />
                    <ModalButton
                        onPress={closeModal}
                        text={'아니오'}
                        width={'110px'}
                    />
                </Row>
            </ModalContainer>
        </ModalSheet>
    )
}

const ModalContainer = styled.View`
  /* 생략 */
`;

 

네이버 로그인 화면

 

로그인 완료 후 DB 저장

 

로그아웃 작동 화면

반응형
profile

my code archive

@얼레벌레 개발자👩‍💻

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

반응형