OAuth 2.0
에서는 4가지의 인증 권한 부여 타입이 존재하는데, 이전부터 언급했듯 Authorization Code
와 Implict
에 대해서만 알아볼 것이다.
일반적으로 SNS로그인 등을 경험해봤다면, 이해하기가 수월할 것이다. RFC 6749
는 HTTP를 전제로 작성되었으므로, 리다이렉션 과정이 필수적이다. 이제 각 단계에서 어떤 값들이 필요한지 살펴보자.
처음 시작은 Resource Owner
가 Client
로부터 페이지를 응답받아 어떤 버튼을 클릭하는 것으로 시작할 것이다(예를 들어 페이스북 로그인 등).
이 때, 이 링크에는 Resource Owner
가 Authorization Server
로 이동할 때 Authorization Server
가 Client
에 대한 정보를 판단하기 위한 값들이 들어있을 것이다.
response_type
Authorization Code
에서는 반드시 code여야 한다.client_id
Client
가 Authorization Code
에 등록하고 난 뒤 부여받은 값redirect_uri
redirect_uri
중 하나. 만약 기본값 설정같은 것이 있다면 따로 필요 없다.Resource Owner
가 인증 후 결과값을 처리할 페이지가 redirect_uri
다.scope
state
Client
에서 전달해준다. 나중에 Authorization Server
는 이 값을 그대로 돌려주면 된다.명세에서 예시로 드는 HTTP 메세지는 아래와 같다.
GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz&redirect_uri=https%3A%2A%2Aclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: server.example.com
Resource Owner
가 인증 후, Client
의 redirect_uri
로 리다이렉트 되어 이동할 때 Authorization Server
에서 바인딩해준 값들은 아래와 같아야 한다.
code
state
Client
가 요청했을 때 있었다면 반드시 응답되어야 한다.HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=Splx1OBeZQQYbYS6WxSbIA&state=xyz
Authorization Server
에 필요한 정보가 없이(예를 들어 client_id
등) Resource Owner
가 넘어온 경우, Authorization Server
는 이에 대한 에러를 Resource Owner
에게 알려주는 것이 좋다(SHOULD). 그리고 절대로 redirect_uri
로는 리다이렉트 시키면 안 된다. 보통 이런 경우는 없어야 하므로 Client
개발자는 신경써서 구현해야 한다.
Resource Owner
가 인증 후 발생한 에러의 경우, Authorization Server
는 에러 정보와 함께 Resource Owner
를 redirect_uri
로 리다이렉트 시켜주면 된다.
참고로 URI
에 바인딩 되는 값들이므로, 오직 ASCII
만을 허용한다. (Unicode
는 허용하지 않음)
error
invalid_request
unauthorized_client
client
의 경우unsupported_response_type
invalid_scope
scope
값이 유효하지 않은 경우 server_error
temporarily_unavailable
error_description
error_uri
Client
개발자가 에러 메세지를 확인할 수 있는 문서화된 URI
가 존재한다면, 그 링크 주소를 나타낸다.state
Client
가 요청했을 때 있었다면 반드시 응답되어야 한다.HTTP/1.1 302 Found
Location: https://client.example.com/cb?error=access_denied&state=xyz
Resource Owner
가 얻어온 Authorization Code
값을 이용해서 Client
는 Token Endpoint
에 Access Token
과 Refresh Token
을 얻을 수 있다.
이 때의 요청은 이전에도 언급했지만, POST
메서드만을 허용한다.
grant_type
code
code
값이어야 한다.redirect_uri
Authorization Request
시에 redirect_uri
를 명시했었다면, 반드시 똑같은 값으로 포함되어야 한다.client_id
보통의 경우, Client
는 반드시 Client Authentication
과정을 거쳐야 한다.
Post /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code\SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
이 과정에서 Authorization Server
는 반드시 아래의 과정을 처리해야한다.
Client Authentication
Authorization Code
인증redirect_uri
값 유효성 검증 및 비교(최초 Authorization Request
과정에서 포함되었던 경우)
Access Token
응답에 대한 스펙은 여러 섹션(#5 Issuing an Access Token, #7 Accessing Protected Resources)에 걸쳐 정의되어 있는데, 이를 한 번에 정리하도록 하겠다.
인증이 완료되면 Authorization Server
는 기본적으로 Access Token
과 함께 필요한 경우 Refresh Token
등 여러 정보를 응답해주면 된다.
응답 바디의 Content-Type
은 반드시 application/json
이어야 한다.
access_token
token_type
token_type
은 RFC 6750을 따른다. 우린 그 중 Bearer
타입만을 사용할 것이므로, 일반적인 경우 bearer
이 될 것이다.
expires_in
refresh_token
scope
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"2YotnFZFEjrlzCsicMWpAA",
"token_type":"bearer",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2T1KWIA",
"example_parameter":"example_value"
}
Authorization Code Grant
를 지금까지 알아보았는데, Implict Grant
는 거의 대부분의 과정이 Authorization Code Grant
와 비슷하다. 다만, 한가지 차이가 있다면 Authorization Code
를 발급받아 Client
가 다시 Authorization Server
로 Access Token
을 요청하는 것이 아닌, Resource Owner
가 애초에 Access Token
값을 갖고 온다는 차이가 있다.
이는 추가적인 요청이 1회 줄어듦을 의미한다.
플로우 다이어그램을 보면 알 수 있듯, Resource Owner
가 이미 Access Token
을 갖고 오기 때문에 Client
는 바로 Access Token
을 사용할 수 있다.
이는 Authorization Code Grant
방식에서 필수로 존재하는 Client Authentication
과정이 생략된 것이라고 볼 수 있다.
이러한 방식은 요청의 횟수가 줄어든다는 장점과, Access Token
이 Resource Owner
에게 노출된다는 단점이 있다.
Authroization Request
과정은 Authorization Code Grant
의 Authorization Request
과 같다. 다만 Implict Grant
에서는 Authorization Request
의 결과로 Access Token Response
를 받는 다는 점에 차이가 있다.
Access Token Response
스펙 역시 Authorization Code Grant
와 같다. 단, 몇 가지 명심해야 할 점이 있다.
refresh_token
을 응답하면 안 된다.Authoriation Request
는 보통의 경우 GET
메서드로 요청되므로, 이 때에는 결괏값이 URI
에 바인딩 되어야 한다.OAuth 2.0
에서 가장 중요하다고 볼 수 있는 스펙에 대해서 알아보았다. 이제, OAuth 2.0
을 구현하는데 필요한 기초정보는 모두 알아보았으므로 이제 다음 챕터부터는 Golang
을 이용해서 OAuth 2.0
을 직접 구현해볼 것이다!
(다음 챕터가 언제 발행될지는 잘 모르겠다🤣)
좋은 글 감사합니다.