[react-native] Expo로 OAuth 구현(구글 로그인) with firebase

gigi·2022년 12월 5일
1

로그인 스크린 및 구글 로그인 버튼까지 구현 한 이후의 작업이다.

  1. google developers
    https://console.cloud.google.com
    해당 주소에 접속하여 프로젝트를 생성한다.
  1. 메뉴 -> API 및 서비스 -> OAuth 동의 화면 이동

type은 외부로하고 필수 항목만 적고 넘어가도록 하자

  1. 메뉴 -> API 및 서비스 -> 사용자 인증 정보로 이동
  • 사용자 인증 정보 만들기 버튼 클릭

승인된 자바스크립트 원본에는

승인된 리디렉션 URI에는

를 넣어주자.

yourname은 expo 로그인할때의 이름, 
your-app은 app.json에 적혀있는 프로젝트 name이다. (정확히는 app.json의 slug)
// app.json의 name은 우리가 사용하는 앱의 실제 이름이다. ex) 스마트폰에 설치한 앱에 표시되는 이름

그러면 clientId 키값이 생성 되는데 이를 아래 코드를 참고하여 넣고 구글로그인 버튼 터치 시 onPress 이벤트로 promptAsync()를 실행하면 된다.

또 onAuthStateChanged 메서드를 통해 로그인한 유저의 정보를 받을 수 있다.

import * as React from 'react';
import * as WebBrowser from 'expo-web-browser';
import { ResponseType } from 'expo-auth-session';
import * as Google from 'expo-auth-session/providers/google';
import { initializeApp } from 'firebase/app';
import { getAuth, GoogleAuthProvider, signInWithCredential, onAuthStateChanged } from 'firebase/auth';
import { Button } from 'react-native';

// Initialize Firebase
initializeApp({
  /* Config */
});

WebBrowser.maybeCompleteAuthSession();

export default function App() {

  const [request, response, promptAsync] = Google.useIdTokenAuthRequest(
    {
      clientId: 'Your-Web-Client-ID.apps.googleusercontent.com',
    },
  );

  React.useEffect(() => {
    if (response?.type === 'success') {
      const { id_token } = response.params;
      const auth = getAuth();
      const credential = GoogleAuthProvider.credential(id_token);
      signInWithCredential(auth, credential);
    }
  }, [response]);
  
  onAuthStateChanged(auth, async (user) => {
    if (user) {
      const { uid, email, displayName, accessToken } = user;
      console.log("uid :", uid)
      console.log("email :", email)
      console.log("displayName :", displayName)
      console.log("accessToken :", accessToken)
    }
  });
  
  return (
    <Button
      disabled={!request}
      title="Login"
      onPress={() => {
        promptAsync();
      }}
    />
  );
}

여기까지는 개발과정에서 expo를 이용해 구글로그인이 가능하다.


문제는 배포 후에 구글로그인 버튼을 누르면 에러가 나게 되는 경우이다.

결과부터 말하자면 해결방법은 쉽다. (공식문서대로 따라하고 app.json 설정만 잘 했다면 문제없이 동작한다)

그렇지만 그와 관련해 구글링을 해보면서 expo cli로 프로젝트를 진행했을때의 문제점이 좀 있었다.
일단 expo cli의 장점은 셋팅의 수고가 없고 간편하다는 점이다. 하지만 expo에서 제공하는 기능만 사용이 가능하다는 점 때문에 구글로그인 방법뿐만 아니라 react-native와 관련 된 정보를 찾아볼때 expo에서 적용해 볼 수 없는 경우가 꽤 있었다.

그리고 사람들마다 말이 다 다르다. webView를 이용해야한다, 해당 API는 더이상 사용할 수 없다, 또 개발환경에서는 동작하지만 배포환경에서는 동작하지 않느다 등등...

정보가 많으면 다수의 동일한 의견을 참고해보고 동작하지않으면 다른 원인을 찾아봤겠지만, 가뜩이나 부족한 정보에서 사람들마다 말이 달라서 혹시나 하는 마음에 거의 모든 경우를 시도 해 본것 같다.
(다시 한번 느끼지만 여러 블로그를 참고하기 어려우면 공식문서를 다시 정독 해보도록하자)


일단 배포 후에 구글로그인을 사용하기 위해서는 사용자 인증 정보에서 Android 유형도 하나 만들어 줘야하는데 SHA-1 키가 필요하다.

  • 해당 프로젝트경로에서 expo credentials:manager -p android 명령어를 실행한다.
  • "Update upload Keystore"를 선택
  • "Generate new keystore"를 선택
  • "Go back to experience overview"를 선택

사용자 인증정보 Android 유형에서 패키지 이름과 함께 위에서 발급한 SHA-1키를 입력해준다.

개발환경에서 구성했던 코드에서 androidClientId도 추가 해주도록 하자.

// ...

const [request, response, promptAsync] = Google.useIdTokenAuthRequest({
    expoClientId: GOOGLE_CLIENT_ID,
    androidClientId: ANDROID_GOOGLE_CLIENT_ID,
  });

// ...

여기까지했는데도 에러가 발생한다면 아마 내가 겪었던 문제와 비슷하게 app.json 설정이 잘못돼서 발생한 에러일 가능성이 높다.

  • firebase 내 앱 설정 후 google-servies.json 다운 받아 app.json 과 같은 위치에 넣어준다.
{
  "expo": {
    "name": "모두의 추천목록",
    "slug": "similarmate",
	"android": {
      "package": "com.gigichoi.similarmate",
      "googleServicesFile": "./google-services.json",
    }
    "scheme": "com.gigichoi.similarmate",
  }
}

(해당 기능에 문제가 되었던 부분만 적었다, 이외에도 splash, version, permissoins 등 다양한 속성이 있다.)

  • android에 package 값으로 패키지이름을 넣어준다.
  • googleServicesFile 경로를 설정해준다.

나같은 경우 중간에 프로젝트 이름을 변경하면서 slug와 package, scheme의 appName이 불일치 하는 경우가 발생했다. 이를 맞춰주고 빌드를 다시 하니 배포 후에도 구글 로그인이 잘 동작하였다.

firebase에서 Authentication 설정도 잘 해줬다면 로그인 한 유저의 등록도 잘 되고 해당 유저의 정보도 onAuthStateChanged 메서드를 통해 잘 들어 올 것이다.

참고
https://docs.expo.dev/guides/authentication/#google
https://github.com/choigicheol/sameMate

0개의 댓글