리액트로는 카카오 로그인을 구현해 본 경험이 있지만 리액트 네이티브는 처음이라 조금 헤맸다.
아직 완성은 못했지만 단계별로 차근차근 기록해보려 한다.
- npm & Expo Bare Workflow & android(window) 사용하였다.
- 사용한 라이브러리
https://github.com/crossplatformkorea/react-native-kakao-login?tab=readme-ov-file
GitHub - crossplatformkorea/react-native-kakao-login: react-native native module for Kakao sign in.
react-native native module for Kakao sign in. Contribute to crossplatformkorea/react-native-kakao-login development by creating an account on GitHub.
github.com
- 참고 블로그
https://mycodearchive.tistory.com/308
https://it-amin.tistory.com/131
0️⃣ Kakao developers 어플리케이션 생성
https://developers.kakao.com/console/app
위 링크로 들어가 카카오 로그인을 한 후 어플리케이션을 추가해준다.
앱이름은 drivemate, 회사명은 팀이름인 X10으로 설정하였다.
1️⃣ 안드로이드 플랫폼 등록
생성된 어플리케이션을 클릭한 후 앱 설정 > 플랫폼으로 이동한다.
나는 안드로이드로만 개발하기 때문에 안드로이드 플랫폼 등록만 진행하였다.
패키지명을 입력하고, 키 해시를 등록한다.
패키지명은 아무거나 설정해도 되는 것 같은데 혹시 몰라서 나는 app.json의 name으로 등록했다.
→ com.drivemate
키 해시는 기본 디버그 키 해시인 Xo8WBi6jzSxKDVR4drqm84yr9iU= 를 등록하였다.
위 라이브러리 readme에 아래와 같이 나와있어 나는 키 해시 등록은 따로 진행하지 않고 기본 디버그 키스토어의 키 해시를 복사해서 플랫폼에 등록하였다.
React Native 0.60.x 부터 템플릿에 기본적으로 디버그 키스토어가 포함되어 있습니다.
(project/android/app에 디버그 키스토어가 존재합니다.)
기본 디버그 키스토어의 key hash 는 Xo8WBi6jzSxKDVR4drqm84yr9iU= 를 사용하시면 됩니다.
2️⃣Kakao developers 카카오 로그인 활성화
3️⃣ 네이티브 앱 키 복사
앱 설정 > 앱 키로 들어가서 네이티브 앱 키를 복사한다.
4️⃣ Redirect URI 설정
android/app/src/main/AndroidManifest.xml에 아래 코드를 추가한다.
주의할 점은 네이티브 앱 키를 적을 때 kakao 뒤에 붙여서 바로 적어야 한다.
예를 들어, 네이티브 앱 키가 abc123일 경우, android:scheme="kakaoabc123" /> 이렇게 적어야한다.
// 생략
<application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="false" android:theme="@style/AppTheme" android:supportsRtl="true">
<activity android:name=".MainActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.App.SplashScreen" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<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="drivemate" />
</intent-filter>
</activity>
// 추가된 부분
<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" />
<!-- Redirect URI: "kakao{NATIVE_APP_KEY}://oauth“ -->
<data android:host="oauth"
android:scheme="kakao + 네이티브앱키" />
</intent-filter>
</activity>
</application>
</manifest>
다음으로 android/app/src/main/res/values/strings.xml에 아래 코드를 추가한다.
이 부분도 위 경우와 마찬가지로 네이티브 앱 키만 바로 적으면 된다.
예) <string name="kakao_app_key">abc123</string>
<resources>
<string name="app_name">drivemate</string>
<string name="kakao_app_key">네이티브 앱 키</string>
</resources>
5️⃣ android/build.gradle에 Maven 추가
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext {
buildToolsVersion = findProperty('android.buildToolsVersion') ?: '35.0.0'
minSdkVersion = Integer.parseInt(findProperty('android.minSdkVersion') ?: '24')
compileSdkVersion = Integer.parseInt(findProperty('android.compileSdkVersion') ?: '35')
targetSdkVersion = Integer.parseInt(findProperty('android.targetSdkVersion') ?: '34')
kotlinVersion = findProperty('android.kotlinVersion') ?: '1.9.24'
ndkVersion = "26.1.10909125"
}
repositories {
google()
mavenCentral()
}
dependencies {
classpath('com.android.tools.build:gradle')
classpath('com.facebook.react:react-native-gradle-plugin')
classpath('org.jetbrains.kotlin:kotlin-gradle-plugin')
}
}
apply plugin: "com.facebook.react.rootproject"
allprojects {
repositories {
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url(new File(['node', '--print', "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), '../android'))
}
maven {
// Android JSC is installed from npm
url(new File(['node', '--print', "require.resolve('jsc-android/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim(), '../dist'))
}
google()
mavenCentral()
maven { url 'https://www.jitpack.io' }
// 아래 코드 추가
maven { url 'https://devrepo.kakao.com/nexus/content/groups/public/' }
}
}
android/build.gradle에 가장 마지막 줄 하나만 추가해준다.
6️⃣ 카카오 로그인 테스트 코드 작성
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 Kakao = () => {
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>
</ScrollView>
</View>
<Pressable
style={styles.button}
onPress={() => {
signInWithKakao();
}}
>
<Text style={styles.text}>카카오 로그인</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 Kakao;
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",
},
});
우선 확인만 해보기 위해 위와 같이 코드를 작성했다.
아래와 같이 로그인 버튼을 누르면 링크가 잘 이동하고 로그인을 완료하면 accessToken과 refreshToken을 받은 것이 확인된다.
✅현재까지 구현한 부분
FE 파트) 카카오 로그인 구현 → 카카오에서 토큰(accessToken, refreshToken) 발급 받기
아래 그림은 다른 블로그에서 가져온 그림인데 리액트&스프링으로 카카오 로그인을 구현하는 과정이다.
전체 흐름을 앱과 비교하기 위해 아래 그림을 가져왔다.
현재 리액트 네이티브로 5번까지 진행이 된 상태이다.
하지만 BE로 인증 코드를 전송하지 않고 토큰을 카카오에서 BE이 아니라 FE이 받은 상태이다.
그래서 이 토큰을 kakao에서 BE로 넘기는게 아니라 FE에서 BE으로 넘기는 방식이다.
이후 BE이 6번부터 진행하면 될 것 같다.
✅전체 흐름
FE) 카카오 로그인 구현 → 카카오에서 토큰(accessToken, refreshToken) 발급 받기 → 토큰 BE로 넘기기
BE) 사용자 인증 후 DB 저장 → 자체 토큰 FE로 발급
FE) 회원가입 여부에 따라 리다이렉트 + 토큰 앱 스토리지에 저장
아마 이렇게 진행될 것 같은데 아직 안해봐서 잘 모르겠다..
진행 중 변경되면 이 블로그 글도 업데이트할 예정이다 !
'졸업 프로젝트 > React-Native' 카테고리의 다른 글
[React-Native] floating 버튼 구현 (0) | 2025.01.22 |
---|---|
[React-Native] 프로젝트 초기 셋팅 (1) | 2025.01.15 |
[React-Native] 초기 셋팅 및 프로젝트 생성 (1) | 2025.01.07 |