이번에 React Native를 이용한 사이드 프로젝트를 하나 진행하게 되었다.
공식 문서에서 CLI 방식이 아닌 Expo로 시작하기를 권장했고, 이에 Expo로 프로젝트를 진행했다.
이 프로젝트에서는 애플, 카카오톡, 네이버, 구글 총 4개의 소셜 로그인이 필요했다. 이 4개를 각각 어떻게 구현했는지 적어보고자 한다.
⚠️ 읽기 전 확인해 주세요 ⚠️
- 이 글은 iOS 기준으로 작성되었습니다.
- 애플을 제외한 소셜 로그인 테스트 시 npx expo run:ios 혹은 npx expo run:android로 테스트해야 합니다.
Expo에서 Expo AppleAuthentication라는 라이브러리를 지원하여 손쉽게 구현할 수 있게 해주었다.
개인적인 생각으로 앱 스토어 통과를 하기 위해 애플 로그인이 필수라 그런 것 같기도..?!
아무튼 아래 과정을 통해 애플 로그인 세팅을 해준다.
npx expo install expo-apple-authentication
// app.json
{
"expo": {
"ios": {
"usesAppleSignIn": true
},
"plugins": ["expo-apple-authentication"]
}
}
세팅을 마치고 나면 예시 컴포넌트를 이용해 애플 로그인을 테스트할 수 있다.
이때 시뮬레이터로 하는 것에는 제한이 있기 때문에 실제 기기에 있는 Expo Go를 통해 테스트를 해야 한다. 공식 문서에서도 실제 기기에서 테스트하는 것을 강력히 권장한다.
이렇게 엄청 간편하게 애플 로그인을 구현할 수 있다. 하지만 라이브러리의 특성상 커스터마이징이 굉장히 제한적이라는 것이 아쉬웠다. 특히 버튼 텍스트 종류가 3개밖에 안될뿐더러 커스터마이징이 안된다…
CLI를 쓸 때에는 react-native-kakao-login을 사용했었는데, react-native-kakao라는 새로운 라이브러리를 발견하여 이것을 사용해 보았다.
새로운 라이브러리는 공식 문서 홈페이지도 있고 여기에 Expo 관련 설정도 자세히 나와 있어서 편하게 할 수 있었다.
카카오 디벨로퍼에서 애플리케이션을 생성 후 필요한 라이브러리들을 설치하고 app.json
을 세팅한다.
// 공통 패키지 설치
npx expo install @react-native-kakao/core
// expo-build-properties 설치
npx expo install expo-build-properties
// 카카오 로그인 및 관련 기능을 담고 있는 패키지 설치
npx expo install @react-native-kakao/user
// app.json
"plugins": [
[
"expo-build-properties",
{
"android": {
"extraMavenRepos": [
"https://devrepo.kakao.com/nexus/content/groups/public/"
]
}
}
],
[
"@react-native-kakao/core",
{
"nativeAppKey": "{{native app key}}",
"android": {
authCodeHandlerActivity: true,
},
"ios": {
handleKakaoOpenUrl: true,
},
}
]
]
여기서 native app key
는 카카오 디벨로퍼에서 생성한 애플리케이션의 네이티브 앱 키이다.
만약 환경 변수를 통해 앱 키를 넣고 싶다면 app.json
을 app.config.js
혹은 app.config.ts
로 바꾸면 된다. 나는 타입스크립트를 사용하기 때문에 app.config.ts
로 작성했다.
import { ConfigContext, ExpoConfig } from "@expo/config";
const kakaoNativeAppKey = process.env.EXPO_PUBLIC_NATIVE_APP_KEY;
export default ({ config }: ConfigContext): ExpoConfig => ({
...config,
plugins: [
[
"expo-build-properties",
{
android: {
extraMavenRepos: [
"https://devrepo.kakao.com/nexus/content/groups/public/"
]
}
}
],
[
"@react-native-kakao/core",
{
nativeAppKey: kakaoNativeAppKey,
android: {
authCodeHandlerActivity: true,
},
ios: {
handleKakaoOpenUrl: true,
},
}
],
],
})
현재는 .env에 네이티브 앱 키를 두고 EXPO_PUBLIC_NATIVE_APP_KEY
으로 가져오고 있다.
하지만 Expo 공식 문서에서 민감한 정보는 EXPO_PUBLIC_
으로 시작하게 하지 말라고 했기 때문에, 추후에는 키를 가져오는 방식을 수정할 예정이다.
세팅이 끝났다면 카카오 SDK를 초기화 시켜준다. 나는 최상위 _layout.tsx
에서 초기화를 해주었다.
import { useEffect } from "react";
import { initializeKakaoSDK } from "@react-native-kakao/core";
export default function RootLayout() {
const kakaoNativeAppKey = process.env.EXPO_PUBLIC_NATIVE_APP_KEY || "";
...
useEffect(() => {
initializeKakaoSDK(kakaoNativeAppKey);
}, []);
...
그 후 카카오 로그인 버튼을 눌렀을 때 login 함수를 호출하기만 하면 끝이다.
import { login } from "@react-native-kakao/user";
const onKakaoLogin = async () => {
try {
const res = await login();
...
} catch (error) {
console.error(error);
}
};
<AuthButton onPress={onKakaoLogin} type="kakao" />
AuthButton
은 직접 만든 커스텀 버튼이다.
네이버 로그인은 react-native-naver-login 라이브러리를 이용하여 진행했다.
우선 애플리케이션 등록을 통해 프로젝트를 하나 생성한다. 이때 환경 추가에서 iOS 선택 후 다운로드 URL은 우선 아무거나 작성하고, URL Scheme는 나의 경우 bundle identifier를 작성했다. 아래는 예시이다.
✅ bundle identifier 확인 방법
npx expo prebuild
를 입력하면 ios 폴더가 생긴다. 이 폴더를 Xcode에서 실행시키면 아래와 같이 bundle identifier를 확인할 수 있다.
애플리케이션 등록을 완료했다면 아래와 같이 app.config.ts
(혹은 app.json
)을 수정해 준다.
import { ConfigContext, ExpoConfig } from "@expo/config";
const bundleIdentifier = process.env.EXPO_PUBLIC_APP_BUNDLE_IDENTIFIER;
export default ({ config }: ConfigContext): ExpoConfig => ({
...config,
plugins: [
[
"@react-native-seoul/naver-login",
{
urlScheme: bundleIdentifier,
},
],
],
})
카카오와 동일하게 _layout.tsx
에서 초기화를 해준다.
import { useEffect } from "react";
import NaverLogin from "@react-native-seoul/naver-login";
export default function RootLayout() {
const consumerKey = process.env.EXPO_PUBLIC_NAVER_CLIEND_ID || "";
const consumerSecret = process.env.EXPO_PUBLIC_NAVER_CLIEND_SECRET || "";
const appName = process.env.EXPO_PUBLIC_NAVER_APP_NAME || "";
const serviceUrlSchemeIOS = process.env.EXPO_PUBLIC_APP_BUNDLE_IDENTIFIER || "";
...
useEffect(() => {
NaverLogin.initialize({
appName,
consumerKey,
consumerSecret,
serviceUrlSchemeIOS,
disableNaverAppAuthIOS: true,
});
}, []);
...
consumerKey
는 Client ID를 가져오면 되고, consumerSecret
은 Client Secret을 가져오면 된다. 그리고 appName
은 애플리케이션 등록할 때 설정한 애플리케이션 이름을 가져오면 된다.
이제 로그인 버튼을 만들고 호출하기만 하면 끝이다.
import NaverLogin from "@react-native-seoul/naver-login";
const onNaverLogin = async () => {
const { failureResponse, successResponse } = await NaverLogin.login();
...
};
<AuthButton onPress={onNaverLogin} type="naver" />
Expo 공식 문서와 react-native-google-signin 공식문서를 보며 세팅을 했다.
이전 로그인들처럼 프로젝트를 생성해야 한다. 구글 클라우드에서 프로젝트를 생성하고 API 및 서비스 → 사용자 인증 정보에서 OAuth 클라이언트 ID를 생성한다. 자세한 방법은 공식 문서를 참고하면 좋다.
생성된 OAuth 2.0 클라이언트 ID에서 클라이언트 ID와 iOS URL 스키마를 가져온다. 이를 바탕으로 app.config.ts
와 _layout.tsx
를 설정해 준다.
// app.config.ts
import { ConfigContext, ExpoConfig } from "@expo/config";
const iosUrlScheme = process.env.EXPO_PUBLIC_IOS_URL_SCHEME;
export default ({ config }: ConfigContext): ExpoConfig => ({
...config,
ios: {
infoPlist: {
CFBundleURLTypes: [
{
CFBundleURLSchemes: [iosUrlScheme],
},
],
},
},
plugins: [
[
"@react-native-google-signin/google-signin",
{
iosUrlScheme,
},
],
],
})
// _layout.tsx
import { useEffect } from "react";
import { GoogleSignin } from "@react-native-google-signin/google-signin";
export default function RootLayout() {
const iosClientId = process.env.EXPO_PUBLIC_GOOGLE_CLIEND_ID || "";
...
useEffect(() => {
GoogleSignin.configure({
iosClientId,
});
}, []);
...
iosUrlScheme
는 가져온 iOS URL 스키마이고, iosClientId
는 클라이언트 ID이다.
마지막으로 버튼으로 호출을 하면 완성이다.
import { GoogleSignin } from "@react-native-google-signin/google-signin";
const onGoogleLogin = async () => {
try {
await GoogleSignin.hasPlayServices();
const response = await GoogleSignin.signIn();
...
} catch (error) {
console.error(error);
}
};
<AuthButton onPress={onGoogleLogin} type="google" />
라이브러리 자체에서 제공하는 버튼이 있기에 해당 버튼을 사용해도 좋다.
우여곡절 끝에 소셜 로그인 4개를 모두 완성해 보았다.
마무리하기 전에 Expo로 진행하면서 느끼게 된 장,단점을 말해보고자 한다.
CLI는 라우팅 설정부터 라이브러리 설정까지 정말 번거로운 점들이 너무 많았다. 하지만 Expo에서는 라우팅 설정은 물론이고 최소한의 라이브러리들을 제공함으로써 개발을 너무도 편리하게 해주었다.
특히 네이티브 코드를 건드릴 필요 없이 app.json
이라는 설정 파일을 통해 라이브러리를 손쉽게 설정할 수 있다는 점이 매력적인 것 같다.
하지만 제공된 라이브러리를 손쉽게 설정할 수 있는 만큼 자유도는 떨어지는 것 같다. 당장 애플 로그인 버튼만 봐도 그렇다. 그리고 이건 개인적인 느낌이지만 CLI에 비해 네이티브 기능을 많이 사용할 수 없는 것 같다.
누군가 “React Native를 시작하려는데 CLI와 Expo 중에 어떤 것을 추천해?” 라고 물어본다면 단연코 Expo를 추천할 것 같다.
동아리 활동만 하다 보니 2024년이 후딱 지나갔고, 새로운 해인 2025년이 왔다. 이번 2025년에는 나를 포함한 주위 사람들이 모두 좋은 일만 가득했으면 좋겠다.
좋은 글 감사합니다.