새해 들어서 React Native로 새 사이드 프로젝트를 진행하고 있습니다. 이번 프로젝트에서는 사용자 인증을 위해 카카오톡 로그인을 간편하게 구현하기로 했습니다. 관련 자료를 찾아보니 예전 자료들이 많고 0.76 버전 이상의 버전에 대해서는 자료가 많이 없어서 제가 적용한 과정에 대해 설명하려고 합니다.
(이번 포스트에서는 react-native-seoul/kakao-login 라이브러리를 사용하여 카카오톡 로그인을 구현하는 방법을 다룹니다.)
내 애플리케이션 생성 하기
우선, 카카오 내 애플리케이션을 생성하는 과정부터 시작하겠습니다.
- 카카오 개발자 사이트에 접속합니다.
- "내 애플리케이션" -> "애플리케이션 추가하기" 버튼을 클릭하여 앱을 생성합니다.
- 생성 후, 카카오 로그인과 OpenID Connect 활성화를 활성화로 설정합니다.
- 생성된 애플리케이션의 네이티브 앱 키를 복사합니다. 이 키는 나중에 여러 곳에서 사용됩니다. (위치는 아래 사진 참고)
- 카카오 로그인을 사용할 플랫폼(Android, iOS)을 모두 등록해야 합니다. (플랫폼 메뉴)
Android 설정
먼저 Android 플랫폼 설정을 진행합니다.
1. 패키지명 등록
프로젝트의 android/app/src/main/AndroidManifest.xml 파일에서 package 속성으로 패키지명을 등록합니다.
2. 키 해시 생성
터미널을 열고, android/app 디렉토리로 이동한 뒤 아래 명령어로 키 해시를 생성합니다.
$ keytool -exportcert -alias androiddebugkey -keystore debug.keystore -storepass android -keypass android | openssl sha1 -binary | openssl base64
안드로이드는 ios에 비해 비교적 쉽다 천천히 따라가자
3. strings.xml 설정
android/app/src/main/res/values/strings.xml 파일에 복사한 네이티브 앱 키를 추가합니다.
4. SDK 적용
android/build.gradle 파일에 아래 코드를 추가합니다.
buildscript {
ext {
buildToolsVersion = "35.0.0"
minSdkVersion = 24
compileSdkVersion = 35
targetSdkVersion = 34
ndkVersion = "26.1.10909125"
kotlinVersion = "1.9.24"
}
repositories {
google()
mavenCentral()
maven { url 'https://devrepo.kakao.com/nexus/content/groups/public/' } // 여기 그대로 추가
}
5. AndroidManifest.xml 설정
AndroidManifest.xml 파일에서 activity 아래에 아래 코드를 추가합니다. 이때 data 부분에 네이티브 앱 키를 정확히 입력해야 합니다.
({ } 괄호는 꼭 제거해야한다. )
...
<activity
android:name="com.kakao.sdk.auth.AuthCodeHandlerActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:host="oauth" android:scheme="kakao{네이티브앱키}" />
</intent-filter>
</activity>
<activity
android:name="com.kakao.sdk.auth.AppsHandlerActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- 배송지 피커를 위한 설정 -->
<data android:scheme="kakao{네이티브앱키}" />
<data android:host="address" />
</intent-filter>
</activity>
...
</application>
</manifest>
iOS 설정
iOS 플랫폼 설정도 진행해야 합니다.
1. 번들 ID 설정
Xcode에서 프로젝트를 열고, General 탭에서 Bundle Identifier 값을 등록합니다. Android와 동일한 값을 사용해야 합니다.
(번들 ID는 통일되어야 에러가 발생하지 않습니다. https://devtalk.kakao.com/t/topic/129366 참고)
2. Info.plist 설정
Info.plist 파일을 열고 CFBundleURLTypes 부분을 수정하여 네이티브 앱 ID를 추가합니다.
(이 부분은 공식 README와 유튜브 영상을 확인하면 쉽습니다.)
우선 xcode에 들어가서 info의 URL Types에 사진처럼 설정
그 후 아래 코드 적용
<key>CFBundleURLTypes</key>
<array>
+ <dict>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>CFBundleURLSchemes</key>
+ <array>
+ <string>kakao{카카오 네이티브앱 아이디를 적어주세요}</string>
+ </array>
+ </dict>
</array>
<key>CFBundleVersion</key>
<string>1</string>
+ <key>KAKAO_APP_KEY</key>
+ <string>{카카오 네이티브앱 아이디를 적어주세요}</string>
+ <key>KAKAO_APP_SCHEME</key> // 선택 사항 멀티 플랫폼 앱 구현 시에만 추가하면 됩니다
+ <string>{카카오 앱 스킴을 적어주세요}</string> // 선택 사항
+ <key>LSApplicationQueriesSchemes</key>
+ <array>
+ <string>kakaokompassauth</string>
+ <string>storykompassauth</string>
+ <string>kakaolink</string>
+ </array>
여기서 설정을 잘 못하면 TypeError or "Cannot read property 'login' of null 에러가 발생합니다.
이 부분을 다시 한 번 점검해 보세요.
3. AppDelegate.mm 수정
AppDelegate.mm 파일에서 아래 코드를 추가하여 카카오톡 로그인을 처리할 수 있도록 합니다. 이 부분은 리엑트네이티브 라이브러리 업데이트로 인해 공식문서와 다르게 수정이 필요할 수 있습니다. 또한, 이 부분은 다른 코드보다 최상단에 위치해야 하므로, 주의 깊게 설정해야 합니다.
#import "AppDelegate.h"
...
#import <RNKakaoLogins.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if([RNKakaoLogins isKakaoTalkLoginUrl:url]) {
return [RNKakaoLogins handleOpenUrl: url];
}
return NO;
}
...
@end
카카오 로그인 코드 구현
이제 카카오 로그인 버튼을 만들어, 로그인, 로그아웃, 프로필 조회 등의 기능을 테스트해보겠습니다.
import {Pressable, ScrollView, StyleSheet, Text, View} from 'react-native';
import React, {useState} from 'react';
import {
login,
logout,
getProfile as getKakaoProfile,
shippingAddresses as getKakaoShippingAddresses,
unlink,
} from '@react-native-seoul/kakao-login';
const App = () => {
const [result, setResult] = useState<string>('');
const signInWithKakao = async (): Promise<void> => {
try {
const token = await login();
setResult(JSON.stringify(token));
console.log('login success ', token.accessToken);
} catch (err) {
console.error('login err', err);
}
};
const signOutWithKakao = async (): Promise<void> => {
try {
const message = await logout();
setResult(message);
} catch (err) {
console.error('signOut error', err);
}
};
const getProfile = async (): Promise<void> => {
try {
const profile = await getKakaoProfile();
setResult(JSON.stringify(profile));
} catch (err) {
console.error('signOut error', err);
}
};
const getShippingAddresses = async (): Promise<void> => {
try {
const shippingAddresses = await getKakaoShippingAddresses();
setResult(JSON.stringify(shippingAddresses));
} catch (err) {
console.error('signOut error', err);
}
};
const unlinkKakao = async (): Promise<void> => {
try {
const message = await unlink();
setResult(message);
} catch (err) {
console.error('signOut error', err);
}
};
return (
<View style={styles.container}>
<View style={styles.resultContainer}>
<ScrollView>
<Text>{result}</Text>
<View style={{height: 100}} />
</ScrollView>
</View>
<Pressable
style={styles.button}
onPress={() => {
signInWithKakao();
}}>
<Text style={styles.text}>카카오 로그인2</Text>
</Pressable>
<Pressable style={styles.button} onPress={() => getProfile()}>
<Text style={styles.text}>프로필 조회</Text>
</Pressable>
<Pressable style={styles.button} onPress={() => getShippingAddresses()}>
<Text style={styles.text}>배송주소록 조회</Text>
</Pressable>
<Pressable style={styles.button} onPress={() => unlinkKakao()}>
<Text style={styles.text}>링크 해제</Text>
</Pressable>
<Pressable style={styles.button} onPress={() => signOutWithKakao()}>
<Text style={styles.text}>카카오 로그아웃</Text>
</Pressable>
</View>
);
};
export default App;
const styles = StyleSheet.create({
container: {
height: '100%',
justifyContent: 'flex-end',
alignItems: 'center',
paddingBottom: 100,
},
resultContainer: {
flexDirection: 'column',
width: '100%',
padding: 24,
},
button: {
backgroundColor: '#FEE500',
borderRadius: 40,
borderWidth: 1,
width: 250,
height: 40,
paddingHorizontal: 20,
paddingVertical: 10,
marginTop: 10,
},
text: {
textAlign: 'center',
},
});
위 사진처럼 로그인 토큰들을 받아오면 성공!
끝
참고 링크
https://www.youtube.com/watch?v=uCn1xIijuos&list=PLMu8UG37vF6oJLNhjsjoy_ApcJFZZwJOo
https://github.com/crossplatformkorea/react-native-kakao-login
'React Native' 카테고리의 다른 글
[React Native] 각종 Clean & 캐시 삭제 및 라이브러리 설치 방법 (0) | 2025.03.08 |
---|---|
React Native 절대경로 설정하기 (0) | 2024.05.31 |
새로운 React Native IDE 사용해보기 (0) | 2024.05.25 |