OAuth 2.0 flow 이해하기 - Backend, GitHub

강병철·2022년 9월 21일
2
post-thumbnail

글을 적으려고 찾아보니 OAuth 방식에도 여러가지가 있다 : OAuth Grant Types

그 중에서 가장 많이 사용되는 Authorization Code 방식의 OAuth flow에 대해 정리해보았다.

OAuth 란?

"인터넷 사용자들이 비밀번호를 제공하지 않고 다른 웹사이트 상의 자신들의 정보에 대해 웹사이트나 애플리케이션의 접근 권한을 부여할 수 있는 공통적인 수단으로서 사용되는, 접근 위임을 위한 개방형 표준" - 위키백과

잘 와닿지 않는다. 쉽게 말해 특정 서비스 A를 이용하기 위해 직접 회원가입을 하지 않고, 다른 서비스 B의 계정을 이용해 로그인 할 수 있게 해주는 방법이다.

여기서 B는 Google이나 GitHub 같이 많은 사람들이 이미 가입해있는 Major Provider 이다.

실생활 예를 들자면, 배달의민족을 이용할 때 따로 회원가입을 하지 않고 Naver 계정을 이용해 로그인 할 수 있게 해주는 것도 OAuth 인증을 이용한 것이다.

OAuth flow

OAuth 2.0은 1.0의 개선 버전으로, 구현이 더 쉬워졌다고 한다.(다행이다)

 +----------+
 | Resource |
 |   Owner  |
 |          |
 +----------+
      ^
      |
     (B)
 +----|-----+          Client Identifier      +---------------+
 |         -+----(A)-- & Redirection URI ---->|               |
 |  User-   |                                 | Authorization |
 |  Agent  -+----(B)-- User authenticates --->|     Server    |
 |          |                                 |               |
 |         -+----(C)-- Authorization Code ---<|               |
 +-|----|---+                                 +---------------+
   |    |                                         ^      v
  (A)  (C)                                        |      |
   |    |                                         |      |
   ^    v                                         |      |
 +---------+                                      |      |
 |         |>---(D)-- Authorization Code ---------'      |
 |  Client |          & Redirection URI                  |
 |         |                                             |
 |         |<---(E)----- Access Token -------------------'
 +---------+       (w/ Optional Refresh Token)

RFC 6749: The OAuth 2.0 Authorization Framework

OAuth 로그인을 구현할 때 가장 많이 참고했던 그림이다. 하지만 한 뭉텅이로 설명되어 있어서 항상 헷갈렸다.

그래서 복습할 겸 그림을 하나하나 쪼개서 설명을 해보려한다.

여기서 Authorization Server는 가장 친숙한 GitHub로 정했다.

0. Authorization Server에 App 등록

내 서비스에서 특정 Authorization Server 의 OAuth 로그인을 이용하기 위해 먼저 등록을 해야한다.
그러면 client_idclient_secrets를 발급받게 된다.

  • GitHub을 이용하는 경우 경우 Settings > Developer settings > GitHub Apps 에서 설정할 수 있다.

  • Provider 마다 등록 방법이 다르므로 검색해 보도록 하자.


1. 최초 로그인 요청

  • 사용자가 GitHub 로그인을 누르면 프론트에서 우리의 백엔드 서버로 GitHub 로그인을 하겠다는 요청을 전달한다.
  • 요청 형식 예시(백엔드가 정한 EndPoint) : GET 서버주소/login/github

2. 깃헙 OAuth App으로 redirect 시켜준다

  • 사용자 화면에 GitHub 로그인 창이 표시되도록 백엔드 서버에서 redirect 시킨다.
  • redirect 주소: GET https://github.com/login/oauth/authorize?client_id=클라이언트아이디&redirect_uri=리다이렉트주소...

    • client_id (필수) : 위에 0 단계에서 발급 받은 것
    • redirect_uri : 유저가 정보를 입력하고 로그인을 누르면 어느 주소로 요청이 갈지 지정
      (ex : 우리서버주소/login/github/callback)

위 요청 주소는 마음대로 정하는게 아니라 GitHub에서 정한 양식이다. 이러한 양식들은 Provider 마다 다르고, 여기서는 OAuth 2의 대략적인 flow만 짚어보는 것이 목적이기 때문에 자세한 설명은 생략하겠다. GitHub를 이용할거라면 여기에서 확인해볼 수 있다.

3. 사용자가 GitHub 계정으로 로그인을 하면, 우리 서버로 code가 전달된다

  • 2단계에서 언급했던 redirect_uricode라는 url parameter가 붙어서 온다. (이 코드를 똑떼서 사용할 것이다)
  • 요청 형식 : GET 우리서버주소/login/github/callback?code=코오오오드

4. code를 이용해 Access Token을 요청하여 받는다

  • 이전 단계들에서 받아뒀던 client_id, client_secret, codeRequest Body에 담아 Post 요청을 보낸다.
  • 요청 형식 : POST https://github.com/login/oauth/access_token
  • 이때 header에 Accept: application/json을 담아 보내면 JSON 형식으로 받을 수 있다.
  • 응답 예시 :
{
  "access_token":"gho_16C7e42F292c6912bcbcbc7Ae178B4a",
  "scope":"repo,gist",
  "token_type":"bearer"
}

5. Access Token을 이용해 로그인한 사용자의 계정 정보를 받는다

  • 요청 형식 : GET https://api.github.com/user
  • Authorization header에 “bearer 토큰값" 와 같은 형태에 맞춰 토큰을 담아 요청한다.
  • 응답 형식 :
{	
	"login": "honeySleepr",
  "id": 92678400,
  "node_id": "U_kgDOBYYpAA",
  "avatar_url": "https://avatars.githubusercontent.com/u/92678400?v=4",
	 ...
}
  • 여기서 받은 계정 정보는 노출되면 안되는 그런 정보가 아니다.
    (id만 알고 있으면 https://api.github.com/users/깃헙아이디를 통해 누구나 얻을 수 있는 정보이다)
  • 우리는 그저 지금 접속한 사용자가 누구인지 확인하기 위해 사용하는 것이다.

6. 끝

여기까지가 OAuth를 통한 사용자 인증 과정이다.

그럼 이제 이 사용자에게 다음 API 요청 때부터 사용할 수 있는 비밀 열쇠 같은 것을 만들어주면 된다.

이를 구현하는 다양한 방법들 중 내가 제대로 구현해본 것은 JWT를 이용하는 방법이다
JWT에 대해서는 다음 글에서 다뤄보도록 하겠다.

읽어주셔서 감사합니다🙇‍ 피드백은 언제나 환영입니다~~

4개의 댓글

comment-user-thumbnail
2022년 9월 22일

서버가 로그인 할 리다이렉트를 주고 code를 직접 받는 방식이군요!
잘봤습니다 BC 짱

1개의 답글
comment-user-thumbnail
2022년 9월 27일

소문 듣고 찾아왔습니다. 후덜덜하네요;; 비씨선생님;;

1개의 답글