팀 프로젝트에서 OAuth 인증을 통한 Github 로그인을 구현했다. 구현 과정에서 OAuth가 나온 배경과 작동 원리가 궁금해졌다. OAuth 인증을 통한 로그인은 실 서비스에서도 많이 사용되기 때문에 간단히 정리해보았다. 나중에 OAuth 로그인을 다시 구현하게 될 때 참고하며 전체적인 흐름을 이해하기 위함이다. 따라서 코드보다는 전체적인 프로세스를 이해하는데 중점을 두고 정리했다.
OAuth의 핵심 역할 →
AccessToken
을 얻어낸다.
내가 만든 서비스에서 다른 서비스(Google,Facebook 등)을 사용하기에 가장 쉬운 방법은 사용자로부터 해당 서비스의 id, password를 입력받아 기억하고 있다가 사용하는 것이다. 하지만 이건 너무 위험하다. 다른 서비스의 아이디, 비밀번호를 전혀 다른 서비스에 공개한다는 건 매우 위험한 선택이다.
이러한 시나리오는 모두에게 있어 불만족스럽다.
사용자: 처음 보는 서비스가 미덥지 않다.
내가 만든 서비스: 만약 문제가 생겼을 경우 지게 될 책임이 부담스럽다.
다른 서비스(Google, Facebook etc): 나만 가지고 있는 사용자 정보를 다른 서비스에서도 접근하는게 싫다.
이러한 문제를 해결하기 위해 나온게 OAuth 이다.
AccessToken
이라는 일종의 비밀키
를 이용한다.AccessToken
을 이용해 해당 서비스의 일부 기능을 이용할 수 있는 것이 OAuth 서비스의 핵심이다.다음 세 개의 객체가 서로 인증 과정을 거친다.
User(Resource Owner)
: 리소스의 주인 (일반 사용자)
App(client)
: 제 3자 앱. User가 사용하는 서비스 (ex. 생활코딩)
Auth server / Resource server
(ex. Google, Github, Facebook etc)
Resource server
: 리소스 저장 서버: API를 통해 리소스를 제공Authorization server
: 인증 담당 서버: 인증을 완료하면 access token을 client 에게 보낸다.OAuth 로그인을 하고자 하는 서비스에서 아래 세 가지 요소를 받아야 한다.
Client ID
: public key 이다. 공개해도 된다.Client Secret
: secret key이다. 공개하면 안 된다. 보통 환경변수에 담아 둔다Redirect URL
: Client ID와 Client Secret을 확인한 후 redirect할 url 주소이다.위 세가지 요소가 모두 일치 했을 때 OAuth 인증이 성공한다.
예를 들어, 깃허브으로 OAuth 로그인을 한다고 할 때,
깃허브에 등록된 Client ID
, Client Secret
, Redirect URL
과 우리가 만든 APP에 등록된 Client ID
, Client Secret
, Redirect URL
이 서로 일치해야한다. 하나라도 불일치하면 OAuth 로그인은 실패한다.
전제
Client ID
, Client Secret
, Redirect URL
을 모두 등록/발급 받은 상태여야 한다.Resource Owner의 승인
Authorization Code
를 보낸다.Authorization Code
를 보낸다.Client ID, Client Secret, Redirect URL, Authorization Code
네 가지를 모두 갖고 있는 상태이다.Auth Server의 승인
Redirect URL
은 optional)redirect_url
을 보내는 건 선택이다.Client ID, Client Secret, Authorization Code 세 가지는 꼭 보내야 한다.
Access Token
을 발급한다.Authorization Code
값은 더 이상 필요없기 때문에 삭제한다.Access Token 발급
Access Token
을 통해서 Resource Server의 기능을 이용할 수 있다.Refresh Token
Access Token
은 cookie처럼 만료 기한이 있다.Refresh Token
이다.Refresh Token
을 발급하지 않는 경우도 있고 쓰는 방식도 다르다.Access Token
은 주로 세션에 저장한다.Refresh Token
은 중요하기 때문에 DB에 저장한다.Refresh Token
이 동작하는 대략적인 원리 아래 그림과 같다.image source: https://tools.ietf.org/html/rfc6749
OAuth의 핵심은 Resource Server로부터 Access Token을 발급 받는 과정이다. Access Token을 발급 받는 과정을 자세히 알아보자.
여기서 Resource Owner
는 웹 사용자라면 브라우저, 모바일 사용자라면 iOS/Android 휴대폰이라고 생각하면 편하다.
clientId
, scope
(가져올 회원 정보 범위), redirect_url
정보가 들어있다.clientId
와 redirect_url
이 일치하는지 확인하고 하나라도 일치하지 않으면 더이상 진행하지 않는다.Authorization Code
를 전달한다.authorization_code
가 전달되며 이 과정에서 App(Client)가 authorization_code
를 알게 된다.Client ID, Client Secret, Redirect URL, Authorization Code
를 모두 보낸다.AccessToken
을 발급한다.Authorization Code
값은 더 이상 필요없기 때문에 삭제한다. (Resource Server, Client 모두)이렇게 발급받은 Access Token
을 통해서 App(Client)는 Resource Server로부터 사용자 정보를 가져올 수 있다.
생활코딩 홈페이지에서 깃허브 로그인하는 과정이라고 가정한다.
사용자가 생활코딩 홈페이지에서 깃허브 로그인 버튼을 누른다.
브라우저는 생활코딩 서버에 로그인 URL
을 요청한다.
생활코딩 서버에서 로그인 URL
을 브라우저에 전달한다.
브라우저는 서버에서 받은 로그인 URL
로 리다이렉트한다.
브라우저에 깃허브 로그인 화면이 뜬다.
사용자는 생활코딩이 요청한 정보(scope) 제공 요청을 승인하고, 자신의 깃허브 아이디와 비밀번호를 입력한다.
깃허브 인증 서버(Auth Server)에서 사용자의 아이디와 비밀번호, 제공할 정보 범위(scope)를 확인한다.
인증이 완료되면 Authorization Code
를 redirect_url
에 붙여 보낸다.
ex) https://redirect_url?code=199b7af5ea11078ee507
생활코딩 서버에서는 Authorization Code
를 받아 Client ID, Client Secret, Authorization Code
를 깃허브 OAuth 서버에 보낸다. (redirect_url은 optional)
깃허브 서버는 Client ID, Client Secret, Authorization Code
가 모두 일치하는지 확인하고, 모두 일치하면 AccessToken
을 생활코딩 서버에 보낸다.
생활코딩 서버는 AccessToken
을 이용해 깃허브의 Resource Server로부터 사용자 정보를 받아온다.