[React-native] 구글 OAuth 로그인

Gyuhan Park·2023년 3월 19일
4

react-native

목록 보기
3/7

OAuth 란?

OAuth : Open Authorization
다른 서비스의 회원 정보를 안전하게 사용하기 위한 방법

사용자가 안전하게 다른 서비스의 정보를 우리 서비스에 줄 수 있다.
자신의 구글 아이디와 비밀번호를 우리 서비스에 알려주지 않아도, 구글에 있는 고객의 정보를 우리 서비스에서 안전하게 사용할 수 있다.

  1. 사용자가 login 버튼을 누른다.
  2. 어플리케이션은 Google Server에 token을 요청한다.
  3. 사용자 인증 성공 시 Google Server가 Authorization code 를 반환한다.
  4. Authorization code로 access token을 요청한다.
  5. Google Server가 access token을 반환한다.
  6. access token을 가지고 로그인을 유지한다.

사용자 인증 성공 시 리다이렉션 URI 파라미터가 승인된 리다이렉션 URI인 경우,
code와 함께 설정한 리다이렉션 URI로 이동

firebase 설정

firebase란?
구글에서 인수한 모바일, 웹 애플리케이션 개발 플랫폼

쓰는 이유?
구글로그인에 사용하는 이유는 복잡한 인증시스템을 지원해준다.

인증된 사용자를 확인하는 세션처리에서 그 세션으로 데이터베이스, 저장소에 접근해도 문제가 없는지 확인하는 보안처리, 비밀번호 찾기, 아이디 찾기, 비밀번호 바꾸기, 이메일 인증 등등 복잡한 것을 구축해야 한다. 하지만 FireBase는 이 모든 것들을 지원한다!

웹 클라이언트 ID 얻기

  • firebase 프로젝트 생성
  • settings -> support email 설정
  • 참여 -> Authentication -> Sign-in-method -> google 추가
  • 웹 클라이언트 ID 저장

REVERSED_CLIENT_ID얻기

프로젝트 개요 -> ios 클릭
2번까지만 하면 된다
필요한 것 : 번들ID, GoogleService-Info.plist

GoogleService-Info.plist 를 ios 폴더 내의 info.plist와 같은 디렉토리에 넣는다.

$ cd ios
$ pod install

xcode -> Build Phases -> Copy Bundle Resources 에 GoogleService-Info.plist 를 추가한다

xcode -> Info -> URL Types 에 추가
Identifier : firebase에서 설정한 번들ID
URLSchemes : GoogleService-Info.plist 안의 REVERSED_CLIENT_ID

구글로그인 구현

라이브러리 설치

$ npm install @react-native-google-signin/google-signin

구글로그인을 위한 config 설정

import {
  GoogleSignin,
  GoogleSigninButton,
  statusCodes,
} from '@react-native-google-signin/google-signin';
import { oauth } from './config/oauth';

const App = () => {
  const googleConfigureSignIn = () => {
    GoogleSignin.configure({
      webClientId: oauth.GOOGLE_WEB_CLIENT_ID,
      offlineAccess: true,
    });
  };

  useEffect(() => {
    checkRecordPermission();
    googleConfigureSignIn();
  }, [RecordPermission]);
}
  
  

accessToken 얻기

accessToken이 왜 필요함? -> 구글 회원인 지 확인하는 용도
구글이 정한 리다이렉션 URI로 accessToken을 담아 요청을 보내면 사용자의 정보를 얻을 수 있다.

  1. 구글 로그인 -> 구글 인증 서버에서 인증 코드(serverAuthCode)를 수신
  2. https://oauth2.googleapis.com/token 에 POST 요청
    다음 코드를 request body에 추가
{
  code: serverAuthCode
  client_id: 클라이언트 ID
  client_secret: 클라이언트 SECRET
  redirect_uri: 승인된 리디렉션 URI
  grant_type: "authorization_code"
}
  1. 구글 인증 서버에서 JSON 객체로 POST 요청에 응답
  2. access_token을 각 API 요청의 Authorization 헤더에 포함
  3. refresh_token을 사용하여 새 access_token을 요청하거나 재인증을 위해 사용자를 Google OAuth 로그인 흐름으로 리디렉션하여 access_token 만료 처리

GoogleSignin.signIn()

await GoogleSignin.hasPlayServices();
const userInfo = await GoogleSignin.signIn();

GoogleSignin.signIn() 의 return 값은 다음과 같다.

id_token
scope
serverAuthCode
user : {email, name, photo}

fetch()

GoogleSignin.signIn() 을 통해 serverAuthCode 를 얻었다.
fetch API를 이용해 아래 URI로 POST 요청을 보내면 accessToken을 얻을 수 있다.

      await GoogleSignin.hasPlayServices();
      const userInfo = await GoogleSignin.signIn();

      const result = await fetch('https://oauth2.googleapis.com/token', {
        method: 'POST',
        body: JSON.stringify({
          code: userInfo.serverAuthCode,
          client_id: oauth.GOOGLE_WEB_CLIENT_ID,
          client_secret: oauth.GOOGLE_WEB_CLIENT_SECRET,
          grant_type: 'authorization_code',
          redirect_uri: oauth.REDIRECT_URI,
        }),
      }).then((res) => {
        return res.json();
      });

fetch() 의 return 값은 다음과 같다.

access_token
expires_in
refresh_token
scope
token_type
id_token

res.json()

status code는 200 인데 데이터에 accessToken이 없었다. 원래 200이 뜨는 건지 데이터를 바꿔보면 그건 또 아니였다. 그럼 정상적인 요청인데 왜 안줌? blob data 어쩌구 저쩌구 이상한 내용만 콘솔에 찍혔다. 뭐지?!??

Response는 HTTP 응답 전체를 나타내는 객체로, JSON 본문 콘텐츠를 추출하기 위해서는 json() 메서드를 호출해야 합니다. json()은 응답 본문 텍스트를 JSON으로 파싱한 결과로 이행하는, 또 다른 프로미스를 반환합니다.

내가 계속 확인한 데이터는 Response 객체였던 거고 내가 원하는 데이터는 객체 안의 JSON 본문 컨텐츠였다.
Response 객체를 json() 을 통해 변환해줬더니 원하는 데이터가 모두 담겨있었다.....

cf) axios는 json() 단계를 자동으로 해준다는데 라이브러리를 최대한 안써서 bundle의 크기를 줄이고 싶었다. 근데 axios 썼으면 몰랐을 듯? 삽질하면서 배우기 ㅎㅎ

결과 😎

서버 연결하면 서버에서 이중 인증을 구현할 예정이다.

OAuth란?

구글 OAuth 로그인

RN firebase 구글로그인 하기

fetch API

profile
단단한 프론트엔드 개발자가 되고 싶은

0개의 댓글