내가 만드는 서비스 A에서 다른 플랫폼(구글 등)의 서비스를 사용하고 싶을 수 있다. 만약 사용자가 직접 서비스 A에 구글 아이디/비번을 입력해서 구글 로그인하면 어떻게 될까? 서비스 A에서 구글 회원 정보를 알고 있으므로 악용할 수 있는 등 보안상 위험 요소가 많아진다.

이때 OAuth를 사용하면, 서비스 A에서 구글 로그인 정보(ID/비번)를 모른채, 구글 서비스를 사용할 수 있다. 이번 글에서는 OAuth의 동작과정에 대해 정리해보았다.

참고로 현재는 OAuth 2.0을 사용한다. OAuth 2.0은 1.0보다 인증 절차가 훨씬 단순하다. 특히 1.0은 직접 암호화를 해서 복잡한 데, 2.0에서는 HTTPS를 통해 암호화를 하기 때문에 훨씬 간단하다! (⇒ 마지막에 관련 이야기가 더 나온다.)

OAuth란

OAuth란, 어떤 서비스(A)다른 플랫폼(구글 등)사용자 정보에 접근하기 위해서, 해당 플랫폼으로부터 접근 권한을 위임받는 프로토콜이다.

이를 통해 사용자가 서비스 A에 직접 구글 ID와 비밀번호를 입력하지 않고도 해당 플랫폼의 데이터에 접근할 수 있다.

OAuth 과정

다음은 OAuth에서의 등장 인물들이다.

  • 리소스 오너(Resource Owner) : 사용자
  • 클라이언트(Client) : 내가 만든 서비스 A
  • 인증 서버(Authorization Server) : 리소스 오너를 인증해주는 서버 (ex. 구글)
  • 리소스 서버(Resource Server) : API를 제공해주는 서버 (ex. 구글)

(이때, 인증 서버와 리소스 서버는 하나의 서버일 수도 있고, 별도의 서버로 분리되어 있을 수 있다.)

과정 전체는 다음과 같다.

img

인증 서버에 클라이언트 등록하기

우선 내가 만드는 서비스 A가 구글의 기능을 사용하고 싶다고 구글에게 얘기해주어야한다.

즉, 인증 서버(구글)에 클라이언트(서비스 A)를 등록해주는 과정이 필요하다.

  • Redirect URI 등록해주기 : 로그인 성공 후 리다이렉션 되는 주소이다. 사용자는 로그인 후, 서비스 A로 돌아가야 하는데 이때 돌아갈 주소를 등록해주어야 한다.
  • Client ID, Client Secret 발급 받음 : Redirect URI를 등록하면, ID와 비밀키를 발급받는다. 이것으로 구글한테 Access Token을 발급받는다. (비밀키는 유출 금지)
로그인하기

1️⃣ 사용자가 클라이언트(서비스 A)에서 구글 로그인 버튼을 클릭한다.

2️⃣ 그러면 서비스 A는 Authorization URL(구글 로그인 페이지)를 제공해준다.

3️⃣ 사용자는 Authorization URL(구글 로그인 페이지)에서 ID/비번을 입력한다.

그러면 서비스 A에서는 사용자의 ID/비번을 모르지만, 구글에 로그인 할 수 있다. 로그인이 성공하면, 다음 순서가 진행된다.

로그인 성공 후, Redirect URI로 리다이렉션

4️⃣ 인증 서버(구글)는 사용자에게 Redirect URI를 보낸다. 이때, Authorization Code를 발급하여 Redirect URI에 포함하여 전송한다.

5️⃣ 사용자는 Redirect URI로 리다이렉션한다. 그리고 이때, 서비스 A에게 Authorization Code를 보낸다. (이 Authorization Code는 Access Token을 발급받기 위한 코드이다. 후에 서비스 A가 Access Token을 받을 때, 이 코드를 함께 보낸다.)

Access Token 발급받기

6️⃣ 서비스 A는 Authorization Code, Client-ID, Client-Secret, Redirect URI를 인증서버에 보낸다. 그리고 인증 서버(구글)로부터 Access Token을 받는다.

그러면 여기까지가 로그인 후, Access Token을 발급받는 과정이다! 이후부터는 Access Token으로 리소스 서버에 접근한다. 즉 사용자가 구글 기능을 사용하려면, 서비스 A는 Access Token으로 리소스 서버에서 해당 API를 호출하게 된다.

+) Access Token은 HTTPS!로만 전송된다.
  • 초반에 OAuth 1.0은 직접 암호화를 하는 반면, 2.0은 HTTPS에 암호화를 위임한다고 했었다. ⇒ 클라이언트가 인증 서버로부터 Access Token을 받을 때 HTTPS를 사용한다.
  • Access Token은 유출되면 안되기 때문에 항상 HTTPS을 통해서 보낸다.
+) Access Token이 노출되면 위험하지 않을까?
  • 그래서 Access Token의 유효기간을 짧게 설정하고, Refresh Token을 사용하여 갱신한다. (인증 서버로 부터 Access Token을 받을 때 Refresh Token도 함께 받는다.)
  • Access Token이 만료되면, 리소스 서버는 오류를 반환한다. 그러면 서비스 A는 Refresh Token을 보내서 새 Access Token을 발급받는다.