OAuth 2.0 - Authorization code Grant
웹 표준 인증 프레임 워크중 access token의 사용으로 여러 디바이스의 인증을 손쉽게 해준 OAuth 2.0 에서 access token를 얻는 여러 방법 중 하나인 Authorization Code Grant를 보자.
Authorization Code Grant
OAuth 2.0에서 가장 많이 볼 수 있는 유형이다. 웹 앱이나 native 앱에서 access token을 얻는데에 사용되는 인증이다.
다른 인증과의 큰 차이점은 앱이 브라우저를 띄워 인증을 시작한다.
인증 과정
공식 문서의 인증 과정은 이렇다.
좀 쉽게 얘기하면 다음과 같다.
- 어플리케이션이 OAuth 서버에 요청해 브라우저를 열어 사용자가 인증을 진행하게 한다.
- 사용자는 브라우저에서 나오는 인증 프롬프트로 인증 후 어플리케이션의 요청을 승인한다.
- 사용자는 OAuth 서버에서 인증코드를 받아 어플리케이션으로 돌아온다.
- 어플리케이션은 인증 코드를 access token으로 교환해준다.
사용 이유
웹과 모바일 앱에서 가장 많이 사용되며, access token을 얻기 위한 인증 코드를 교환하는 단계가 더 있어 보안에 더 효과적이다.
코드를 교환하는 단계에서 access token이 항상 보호된 backchannel에서 응용 프로그램과 OAuth 서버를 이동하기 때문에 공격자가 중간에 가로챌 수 없다.
Request & Response Example
1. 클라이언트 정보와 함께 OAuth 서버에 요청
GET /auth
?response_type=code
&client_id=s6BhdRkqt3&state=xyz
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
&scope=create+delete
&state=xcoiv98y3md22vwsuye3kch
Host: server.example.com
response_type=code
: 어플리케이션이 Authorization Code 인증을 시작하고 있음을 OAuth 서버에 알린다.client_id
: 개발자가 어플리케이션을 처음 등록 할 때 얻은 어플리케이션의 공개 식별자.redirect_uri
: 요청을 승인 한 후 사용자를 다시 보낼 위치를 OAuth 서버에 알립니다.scope
(optional) : 어플리케이션이 요청한 사용 권한을 나타낸다.state
(optional) : 어플리케이션에서 임의의 문자열을 생성하고 요청에 포함시킵니다. 그런 다음 사용자가 권한을 인증 한 후에 동일한 값이 반환되는지 확인해야한다. 이것은 CSRF 공격 을 막는 데 사용된다.
client_id
는 어플리케이션을 등록하면 받는 어플리케이션의 고유 식별값이다. client_password
와 함께 인증 코드를 access token으로 교환할 때 제대로된 곳에서 인증을 했는지 확인하는 데 사용된다.
3. 어플리케이션에 돌아오는 응답
https://example-app.com/redirect
?code=g0ZGZmNjVmOWIjNTk2NTk4ZTYyZGI3
&state=xcoiv98y2kd22vusuye3kch
code
: OAuth 서버에서 만들어준 인증 코드.state
: 요청할 때 똑같이 왔는지 어플리케이션에서 확인해야한다.
4. 인증 코드를 access token으로 교환
요청
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
grant_type=authorization_code
: 어플리케이션이 authorization_code 유형을 사용하고 있음을 알린다.code
- 리디렉션에 제공된 인증 코드.redirect_uri
- 코드를 요청할 때 사용 된 동일한 리디렉션 URI입니다. 필요하지 않을 경우도 있다.client_id
- .어플리케이션의 고유 식별 값.client_secret
- 이 값을 사용하면, access token을 얻으려는 요청이 어플리케이션에서만 이루어지며 인증 코드를 가로채는 잠재적인 공격자가 아닌 것이 보장된다.
응답
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3",
"token_type":"bearer",
"expires_in":3600,
"refresh_token":"IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk",
"scope":"create delete"
}
노출되어선 안되는 정보이기 때문에 캐시에 저장되어선 안되기 때문에 헤더에 꼭 아래를 명시하길 권장한다.
Cache-Control: no-store
Pragma: no-cache
참조
- https://tools.ietf.org/html/rfc6749#section-4.1
- https://developer.okta.com/blog/2018/04/10/oauth-authorization-code-grant-type
- https://www.oauth.com/oauth2-servers/access-tokens/authorization-code-request/
- https://developer.okta.com/blog/2018/05/24/what-is-the-oauth2-implicit-grant-type