OAuth 2.0 - Implicit Grant
웹 표준 인증 프레임 워크중 access token의 사용으로 여러 디바이스의 인증을 손쉽게 해준 OAuth 2.0 에서 access token를 얻는 여러 방법 중 하나인 Implicit Grant를 보자.
Implicit Grant
이 유형은 Authorization Code grant
에서 인증 코드 교환과정을 빼고 바로 access token을 발급받는 방법이다.
특별히 안전한 저장공간이 없는 Javascript SPA(Single Page Application)에 사용하기 위해 만들어졌지만 권장하지는 않는 유형이다.
Authorization Code grant
와 마찬가지로 브라우저를 띄워 사용자에게 승인을 요구한다.
인증 과정
공식 문서의 인증 과정
- 어플리케이션이 OAuth 서버에 요청해 브라우저를 열어 사용자가 인증을 진행하게 한다.
- 사용자는 브라우저에서 나오는 인증 프롬프트로 인증 후 어플리케이션의 요청을 승인한다.
- 사용자는 OAuth 서버에서 access token을 받으며 어플리케이션으로 돌아온다. (선택적으로 refresh token)
사용할 때
이 유형은 JavaScript 코드용으로 작성되었으며, Authorization Code 보다 사용하기 쉽지만 단순함으로 얻은 것은 다른 요소에서 손해가 온다. 자바 스크립트 앱은 안전한 저장 공간이 없어 client_secret
없이 승인 코드를 사용해야했다. 하지만 Authorization Code 에서는 Client_secret
이 필요해 다른 접근 방법이 필요했다.
이 유형의 단점은 신뢰할 수 있는 back channel에서 반환되는 것이 아니라 access token이 URL에 직접 반환된다는 것이다.
access token 자체가 브라우저에 기록되므로 대부분 서버는 만료기간을 짧게 발급해 누출될 위험을 줄인다. 하지만 이 유형은 back channel이 없으므로 refresh token
도 사용하지 못한다. 수명이 다한 어플리케이션이 다시 새 access token을 얻으려면 다시 OAuth 승인 과정을 거치거나 숨겨진 iframe
을 사용해 다시 요청하는 등 복잡한 로직이 추가된다
또 다른 사용 이유는 OAuth 서버가 CORS (Cross-Origin Request)를 지원하지 않는 경우이다. Authorization code에서는 JavaScript 응용 프로그램이 권한 서버에 POST 요청을 하도록 요구하므로 OAuth 서버는 브라우저가 해당 요청을 수행 할 수 있도록 적절한 CORS 헤더를 지원해야 한다. 이것은 본인이 OAuth 서버를 작성하는 경우 상대적으로 쉬운 변경이지만, 기존 서버를 사용하는 경우 이 유형을 사용하여 CORS 제한을 피할 수 있다.
Request & Response Example
1. 클라이언트 정보와 함께 OAuth 서버에 요청
GET /auth
?response_type=token
&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=token
: 어플리케이션이 implicit 인증을 시작하고 있음을 OAuth 서버에 알린다.client_id
: 개발자가 어플리케이션을 처음 등록 할 때 얻은 어플리케이션의 공개 식별자.redirect_uri
: 요청을 승인 한 후 사용자를 다시 보낼 위치를 OAuth 서버에 알립니다.scope
(optional) : 어플리케이션이 요청한 사용 권한을 나타낸다.state
(optional) : 어플리케이션에서 임의의 문자열을 생성하고 요청에 포함시킵니다. 그런 다음 사용자가 권한을 인증 한 후에 동일한 값이 반환되는지 확인해야한다. 이것은 CSRF 공격 을 막는 데 사용된다.
client_id
는 어플리케이션을 등록하면 받는 어플리케이션의 고유 식별값이다. client_password
와 함께 인증 코드를 access token으로 교환할 때 제대로된 곳에서 인증을 했는지 확인하는 데 사용된다.
3. 어플리케이션에 돌아오는 응답
https://example-app.com/redirect
#access_token=g0ZGZmNj4mOWIjNTk2Pw1Tk4ZTYyZGI3
&token_type=Bearer
&expires_in=600
&state=xcoVv98y2kd44vuqwye3kcq
바로 access token이 와 사용가능하게 된다.
Url Fragment를 사용하는 이유
access token을 받을 때 #access_token=g0ZGZmNj4mOWIjNTk2Pw1Tk4ZTYyZGI3
같이 url의 Fragment를 사용한다.
역사적인 이유 중 하나는 브라우저가 페이지를 새로고침하지 않고 URL의 단편 부분을 조작 할 수 있다는 것이다. 그러나 이제 History API 는 브라우저가 페이지를 새로고침 하지 않고 URL의 전체 경로와 쿼리 문자열을 업데이트 할 수 있음을 의미하므로 더 이상 이 방식이 이점이 아니다.
참조
- https://tools.ietf.org/html/rfc6749#section-4.2
- https://developer.okta.com/blog/2018/05/24/what-is-the-oauth2-implicit-grant-type