[GCP] GCP에서 사용자 인증정보(OAuth)를 사용해 Access Token 받아오기


Google Calendar에 커피챗 일정을 잡아주는 프로그램을 만드는 중인데, 이 과정에서 Google Calendar API를 사용하기 위해서는 GCP로부터 Access Token 발급을 받아야 하므로 그 방법을 한 번 정리해보자고 한다.
scope부분만 원하는 서비스로 선택하면 해당 서비스의 Access Token을 받을 수 있으며 여기서는 내가 작업 중인 Google Calendar를 예시로 글을 작성해본다.

1. GCP > API 및 서비스 > 사용자 인증 정보에서 OAuth client 생성

이번 포스트에서는 클라이언트 생성 방법보다는 Access Token발급을 중점으로 다루고 있기 때문에 client 세팅 방법은 따로 안내하지 않겠다.

여기에서 우리가 확인해야 할 정보는 다음과 같다.

GOOGLE_CLIENT_ID=<클라이언트 ID>
GOOGLE_CLIENT_SECRET=<클라이언트 보안 비밀번호>
GOOGLE_REDIRECT_URI=<승인된 리디렉션 URI주소>



2. Google Calender의 Access Token요청을 위한 URL 입력

아무 인터넷 창에다가 다음의 url을 입력한다.

https://accounts.google.com/o/oauth2/v2/auth?scope=https://www.googleapis.com/auth/calendar&access_type=offline&include_granted_scopes=true&response_type=code&redirect_uri=<GOOGLE_REDIRECT_URI>&client_id=<GOOGLE_CLIENT_ID>

값이 잘 입력됐다면 google 계정으로 로그인이 나오며, 액세스 허용 여부를 물어보는 페이지를 볼 수 있다.



3. Redirect uri로 받아온 값 확인

위 이미지에서 “허용” 버튼을 누르면 redirect uri로 바로 이동한다.
이 때 주소창을 확인하면 response를 확인할 수 있으며, CODE부분을 잘 백업해두자.
코드의 유효시간은 10분인 것 또한 참고할 것

GOOGLE_REDIRECT_URI/?code=<CODE>&scope=https://www.googleapis.com/auth/calendar

4. Access Token 발급받기

이제 Access Token을 발급받을 준비가 되었다.
다음의 명령어를 입력해보자. curl이니 터미널에 입력하면 된다.

curl --request POST \
  --url https://oauth2.googleapis.com/token \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data "code=<CODE>" \
  --data "client_id=<GOOGLE_CLIENT_ID>" \
  --data "client_secret=<GOOGLE_CLIENT_SECRET>" \
  --data "redirect_uri=<GOOGLE_REDIRECT_URI>" \
  --data "grant_type=authorization_code"

제대로 값이 전달되면 다음과 같은 response를 얻을 수 있다.

{
  "access_token": <ACCESS_TOKEN>,
  "expires_in": 3599,
  "refresh_token": <REFRESH_TOKEN>,
  "scope": "https://www.googleapis.com/auth/calendar",
  "token_type": "Bearer"
}

4-1. Refresh Token을 사용해서 Access Token을 재발급 받기

결과를 보면 expires_in이 있는데, 3599초 즉 1시간만 Access Token을 사용할 수 있으며 이후로는 토큰 사용이 불가능하다.

나처럼 캘린더 일정을 계속 자동화해서 잡아야 하는 경우에는 refresh_token을 이용해서 access_token을 갱신해야 한다.
다행이도 Google OAuth2에서 제공하는 refresh_token은 만료되지 않는다.


만약 refresh_token 을 사용해서 access_token을 재발급 받고 싶으면 다음의 curl을 보내주자.

curl --request POST \
  --url https://oauth2.googleapis.com/token \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data "client_id=<GOOGLE_CLIENT_ID>" \
  --data "client_secret=<GOOGLE_CLIENT_SECRET>" \
  --data "refresh_token=<REFRESH_TOKEN>" \
  --data "grant_type=refresh_token"

갱신 요청이 성공하면 새로운 access_token이 반환된다.

{
  "access_token": <ACCESS_TOKEN>,
  "expires_in": 3599,
  "scope": "https://www.googleapis.com/auth/calendar",
  "token_type": "Bearer"
}

5. JS코드로 Access Token (+Refresh Token으로 재발급까지)을 받아보자

이러한 작업들을 일일이 하기에는 여러모로 피곤하니, 코드로 한 번 구현을 해봤다.

만약 이 코드를 돌렸는데 403 Forbidden이 나온다면 GCP에서 현재 사용하는 서비스의 API 사용을 허가했는지 확인해보자.
서비스 리스트는 https://console.cloud.google.com/apis/api 에서 확인할 수 있다.

# .env.local
GOOGLE_CLIENT_ID=<클라이언트 ID>
GOOGLE_CLIENT_SECRET=<클라이언트 보안 비밀번호>
GOOGLE_REDIRECT_URI=<승인된 리디렉션 URI주소>
GOOGLE_REFRESH_TOKEN==<refresh token값>
// oauth.js
import { google } from 'googleapis';

async function getOAuth2Client() {
  const oAuth2Client = new google.auth.OAuth2(
    process.env.GOOGLE_CLIENT_ID,
    process.env.GOOGLE_CLIENT_SECRET,
    process.env.GOOGLE_REDIRECT_URI
  );

  // Refresh token 설정
  oAuth2Client.setCredentials({
    refresh_token: process.env.GOOGLE_REFRESH_TOKEN,
  });

  try {
    // Access token 갱신
    const { token } = await oAuth2Client.getAccessToken();
    oAuth2Client.setCredentials({ access_token: token });
    return oAuth2Client;
  } catch (e) {
    console.error('Failed to refresh access token:', e);
    throw new Error('Failed to get access token.');
  }
}

Author: Ruby Kim
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source Ruby Kim !
Comments
  TOC