티스토리 뷰
grant_type
OAuth 2.0
프레임워크의 핵심은 다양한 클라이언트 환경에 적합한 인증 및 권한의 위임 방법(grant_type
)을 제공하고 그 결과로 클라이언트에게access_token
을 발급하는 것이다.- 한 번 획득된
access_token
은 만료 시점까지 모든 리소스 서버의 엔드포인트 요청 헤더에Authorization: Bearer {ACCESS_TOKEN}
로 첨부된다. - 사용자의 인증 과정에 개입하는 2가지 방식(
authorization_code
,implicit
)과 사용자가 인증 과정에 개입하지 않는 2가지 방식(password
,client_credentials
)이 있다. 마지막으로 만료된 access_token을 재발급 받기 위한refresh_token
이 있다.
authorization_code
- 클라이언트가 백엔드를 제공하는 웹 애플리케이션이면 authorization_code 인증을 사용한다. [관련 링크]
GET https://{oauth2_server}/oauth/authorize
?response_type=code
&client_id={client_id}
&redirect_uri={redirect_uri}
&scope={scope}
- 사용자가 클라이언트가 요청한 scope에 대한 권한 위임에 동의하면 아래와 같이 응답한다.
HTTP/1.1 302 Found
Location: {redirect_uri}?code={code}
- 사용자 브라우저에서는 redirect_uri가 가리키는 클라이언트의 백엔드 웹 서버로 아래와 같이 GET 요청을 수행한다. 클라이언트는 이 시점에 사용자가 권한 위임에 동의한 code를 획득할 수 있지만 아직 access_token은 모르는 상태이다.
GET {redirect_uri}?code={code} HTTP/1.1
Host: {redirect_host}
- 클라이언트의 백엔드는 아래와 같이 획득한 code를 인증 서버에 요청하여 access_token을 발급 받는다. 이 과정에서 access_token은 클라이언트 외부로 유출되지 않는다. 클라이언트의 백엔드가 존재할 경우 가장 안전한 인증 방식이라고 불리는 이유이다.
curl -X POST 'https://{oauth2_server}/oauth/token'
-H 'Authorization: Basic {base64 of client_id:client_sercret}'
-d 'grant_type=authorization_code'
-d 'code={code}'
-d 'redirect_uri={redirect_uri}'
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token": {access_token},
...
}
implicit
implicit
은 authorization_code과 같이 인증 과정에서 사용자의 로그인 및 권한 동의를 요구하는 타입이다.implicit
은 웹 서버가 아닌 모바일 네이티브 앱 및 브라우저 기반의 JS 애플리케이션(SPA)에 가장 적합하도록 설계된 grant_type타입이다.- authorization_code와의 차이점이라면
response_type
으로code
가 아닌token
을 요청하고 반환한다는 것이다. 사용자가 로그인 및 권한 위임에 동의하면redirect_uri
에token
파라메터를 통해access_token
을 바로 내려준다. - 이 방식은 access_token이 그대로 사용자(또는 외부)에게 노출된다. 유효한 클라이언트인지 확인할 방법은 redirect_uri 뿐이다. (절대 사용자(외부)에 노출되지 않아야 할 client_secret은 전혀 사용되지 않는다.)
- refresh_token 또한 노출되지 않아야 하기 때문에 발급되지 않는다. 따라서 access_token이 만료되면 같은 인증 과정을 반복해야 한다. (Azure AD같은 서비스는 iframe에 세션 쿠키를 유지하는 방법으로 이러한 인증 과정을 생략하기도 한다.)
- [1단계] 클라이언트가 인증 서버에게 사용자 로그인 및 권한 동의 웹 페이지를 요청한다. GET /oauth/authorize?response_type=token&client_id={CLINET_ID}&redirect_uri={CALLBACK_URL}&scope={SCOPE} Yahoo와 같이 다국어 지원 API들은 language 파라메터를 옵션으로 요청 받기도 한다.
- [2단계] 1단계 성공시
POST {CALLBACK_URL}#token={ACCESS_TOKEN}
으로 리다이렉트한다. 이 시점에 클라이언트는 access_token을 획득하게 된다. - [3단계] 획득한 access_token으로 리소스 서버의 엔드포인트로 API를 요청한다.
SPA에서의 implicit 인증 흐름
- SPA는 백엔드가 존재하지 않는 클라이언트로 implicit 인증에 적합하다. 따라서 사용자 브라우저에서 바로 access_token을 획득해야 한다. 아래와 같이 인증 서버에 권한 위임 동의 페이지를 요청한다. 백엔드 외에 노출되지 말아야 할 client_secret은 전달되지 않는다. 인증 서버는 client_id의 redirect_uri가 기존에 등록된 것과 일치하는지 확인한다.
GET https://{oauth2_server}/oauth/authorize
?response_type=token
&client_id={client_id}
&redirect_uri={redirect_uri}
&scope={scope}
- 사용자가 클라이언트가 요청한 scope에 대한 권한 위임에 동의하면 아래와 같이 응답한다.
HTTP/1.1 302 Found
Location: {redirect_uri}#access_token={access_token}
- 사용자 브라우저에서는 아래와 같이 GET 요청을 수행한다. 이 과정에서 access_token은 네트워크에 노출되지 않는다. 사용자 브라우저에서만 access_token을 획득한다. [관련 링크]
GET {redirect_uri} HTTP/1.1
Host: {redirect_host}
- GET 요청이 완료되면 SPA는 JavaScript로 access_token을 확인할 수 있다. refresh_token이 제공되지 않으므로 보통 access_token의 유효기간으로 2주가 제공된다. 2주가 지나면 다시 같은 절차를 반복해야 한다.
window.location.hash; // #access_token={access_token}
password
password
는 사용자의 인증 정보를 클라이언트로부터 보호하는authorization_code
,implicit
과 다르게 클라이언트가 이미 사용자의 인증 정보를 알고 있을 경우 사용할 수 있는 타입이다. 클라이언트가 매우 신뢰할 수 있는 경우에 사용한다. [관련 링크]POST /oauth/token
요청으로 바로 access_token을 획득한다. 필수로 요구되는 파라메터는 client_id, client_secret, grant_type = password, username, password이다.
refresh_token
refresh_token은 access_token을 재발급하기 위한 인증 방식이다. 아래와 같이 인증 서버에 access_token의 재발급을 요청한다.
curl -X POST 'https://{oauth2_server}/oauth/token'
-H 'Authorization: Basic {base64 of client_id:client_secret}'
-d 'grant_type=refresh_token'
-d 'refresh_token={refresh_token}'
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token": {access_token},
...
}
보호된 자원 요청
- 앞서 다양한 인증 방식에 의해 사용자의 권한 위임 정보를 담은 access_token을 획득한 클라이언트는 이제 리소스 서버의 보호된 자원에 접근할 수 있다.
curl -X GET 'https://{protected_resource_server}/resources/1'
-H 'Authorization: Bearer {access_token}'
참고 글
댓글
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 로드 바이크
- 태그를 입력해 주세요.
- chrome
- bootstrap
- 로드바이크
- Kendo UI
- Docker
- Spring MVC 3
- graylog
- Eclipse
- 평속
- CentOS
- spring
- 알뜰폰
- 자전거
- jstl
- kotlin
- node.js
- Tomcat
- jsp
- 구동계
- Spring Boot
- DynamoDB
- JHipster
- MySQL
- maven
- JavaScript
- Kendo UI Web Grid
- jpa
- java
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
글 보관함