일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- Unchecked Exception
- AccountManager
- 다른 앱에서 열기
- ios
- BLOCK
- 페이스북
- ios9
- android studio
- Google Cloud Messasging
- service
- 데이터 공유
- Push
- In-app Billing
- unreal
- HTTP
- Android O
- Google Cloud Messasing
- 트위터
- Activity 수명 주기
- Android
- gradle
- GCM
- 안드로이드 개발 레벨업 교과서
- Android O Preview
- NSURLConnection
- 배포
- 카카오톡
- signing
- contentprovider
- xcode
- Today
- Total
노블의 개발이야기
OAuth 본문
1. 액세스 토큰
OAuth 2.0을 반영한 대부분의 API는 허가된 요청을 만드는데 전달 토큰만 있으면 된다. 전달 토큰은 간단한 토큰 값으로 보호되는 자원에 접근할 수 있게 해주는 액세스 토큰의 한 종류다. API 호출을 만드는 데 필요한 암호 키 같은 추가 정보는 없다.
액세스 토큰을 얻은 후, 그것을 요청에 실어 보낼 수 있다. 액세스 토큰을 요청에 실어 보내는 다양한 방법 중 HTTP 권한 헤더에 액세스 토큰을 포함하는 방법을 선호한다.
GET /tasks/v1/lists/@default/tasks HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer ya29.AHES6ZSzX
개발자들은 아래와 같은 이유로 HTTP 권한 헤더에 액세스 토큰을 포함하는 방법을 선호한다.
- 헤더는 프록시 서버나 웹 서버 접근 로그에 거의 로그를 남기지 않는다.
- 헤더는 거의 캐시되지 않는다.
- 헤더는 클라이언트에서 요청이 만들어질 때 브라우저 캐시에 저장되지 않는다.
response_type
서버사이드 웹 애플리케이션 플로우의 코드로, 사용자가 권한 요청을 승인한 후 애플리케이션으로 리턴되는 권한 코드를 나타낸다.
state
구현물에서 사이트 간 요청 위조 CSRF 공격을 막기 위해 애플리케이션에서 사용되는 유일한 값이다. 이 값은 예측이 불가능하고 클라이언트(아마도 서버사이드 세션 안에)에서 기밀이 유지되는 특정 요청에 대한 무작위 상태 값이어야 한다.
표준 OAuth 질의 파라미터 외에 구글 도구에만 해당하는 몇 가지 파라미터가 있다.
approval_prompt
사용자가 애플리케이션에 방문할 때마다 승인을 위해 사용자에게 알리길 원하면, approval_prompt를 'force'로 설정한다. 사용자가 처음 애플리케이션을 방문할 때만 승인 요청을 보게 하려면 'auto'로 설정한다.
access_type
사용자가 컴퓨터를 사용하지 않는 동안 애플리케이션이 사용자 데이터에 접근하길 원하면, access_type를 'offline'으로 설정한다. 그러면 사용자가 명시적으로 애플리케이션에 접근 허가를 승인할 때 발급되는 재발급 토큰을 가져올 수 있다. 만약, 'online'을 사용하면 재발급 토큰은 발급되지 않을 것이다.
# 에러처리
모든 요청 파라미터가 유효하고 사용자가 데이터 접근 요청을 승인하면, 사용자는 다시 redirect_uri에 명세된 URL의 애플리케이션으로 리다이렉트된다. 그러나 요청 파라미터 중 하나라도 유효하지 않으면 에러가 발생할 것이다.
만약 redirect_uri, client_id 또는 다른 요청 정보에 문제가 있으면, 권한 서버는 사용자에게 에러 메시지를 보여주고 사용자를 애플리케이션으로 리다이렉트하지 않는다. 사용자 또는 권한 서버가 접근 요청을 거부하면, 에러 응답을 생성하고 'access_denied" 같은 에러를 발생시킬 질의 파라미터를 포함한 'redirect_uri'로 사용자를 리다이렉트한다. 추가적으로 권한 서버는 error_escription 메시지나 더 많은 에러 정보를 보여주는 웹 페이지 URL인 error_uri를 나타낼 수 있다.
invalid_request
요청에 필수 파라미터가 빠져 있거나 지원하지 않는 파라미터가 들어 있는 등 비정상적인 경우의 에러 타입니다.
unauthorized_client
클라이언트가 권한 코드를 요청하기 위한 권한이 없는 경우 에러 타입니다.
unsupported_response_type
권한 서버가 권한 코드를 얻는 걸 지원하지 않는 경우의 에러 타입이다.
invalid_scope
요청 범위가 유효하지 않거나, 서버가 알 수 없거나, 비정상적인 경우다.
server_error
권한 서버가 요청을 처리할 때 예상치 않은 상태를 만나는 경우의 에러 타입이다.
temporarily_unavailable
권한 서버가 일시적인 과부하나 유지 보수로 인해, 현재 요청을 다룰 수 없는 경우의 에러 타입니다.
2단계: 권한 코드를 액세스 토큰으로 교환하기
승인 과정에서 에러가 발생하지 않는 경우, 권한 서버는 사용자를 'redirect_uri'로 명세된 URL의 애플리케이션으로 리다이렉트할 것이다. 이 예제에서 사용자는 "http://payroll.saasyapp.com/oauth2callback"으로 리다리렉트된다.
사용자가 접근을 허가하면, 다음 두 질의 파라미터는 권한 서버에 의해 웹 애플리케이션으로 리다이렉트된다.
code
사용자가 접근 요청을 승인했을 때를 나타내는 권한 코드다.
state
권한 서버로 초기 요청이 전달될 때 포함되었던 state 파라미터의 값이다.
상태 값은 앞선 1단계에서 생성된 값과 비교된다. 만약 값이 일치하지 않으면 악의적인 사용자가 애플리케이션에 CSRF 공격을 시도한 것일 수도 있다. 따라서 OAuth 플로우를 중단해야 한다.
http://payroll.saasyapp.com/oauth2callback?code=AB231DEF2134123kj89&state=987d43e51a262f
애플리케이션은 API 요청을 만들기 위해 권한 코드를 OAuth 액세스 토큰으로 교환해야 한다. 만약 OAuth에 대한 클라이언트 라이브러리를 사용한다면, 교환은 일반적으로 라이브러리에 의해 내부적으로 일어난다. 라이브러리를 사용하지 않는다면, 액세스 토큰의 엔드포인트로 HTTP POST 요청을 만들어야 한다.
code
애플리케이션에 전달되는 권한 코드다.
redirect_uri
권한 엔드포인트에 첫 요청을 보낼 때의 등록된 위치다.
grant_type
권한 코드의 액세스 토큰으로의 교환을 나타내는 값(=authorization_code)이다.
HTTP POST는 애플리케이션 등록으로 얻게되는 'client_id'와 'client_secret'을 사용하여 인증된다. 스펙에는 요청을 인증하는 두 가지 기본 방법이 있다.
HTTP Basic Authorization 헤더(사용자 이름을 client_id로, 비밀번호를 client_secret으로 사용)를 포함하는 방법과 HTTP POST 파라미터로 client_id와 client_secret을 포함하는 방법이다.
일반적인 권한 헤더는 다음과 같다.
Authorization: Basic
MDAwMDAwMDA0NzU1REU0MzpVRWhrTDRzTmVOOFlhbG50UHhnUjhaT
WtpVU1nWWlJNg==
HTTP Basic 접근 인증은 OAuth 2.0 스펙에 나중에 추가되었기 때문에, 아직 많은 API 제공 업체가 지원하지는 않는다. 대신 HTTP POST 파라미터 방식이 많이 사용된다.
다음의 추가 POST 파라미터들은 code, state와 함께 사용된다.
client_id
애플리케이션에 등록했을 때 제공되는 값이다.
client_secret
애플리케이션을 등록했을 때 제공되는 기밀이다.
만약 요청이 인증되고 다른 파라미터가 유효하다면, 권한 서버는 JSON-인코딩 응답에 OAuth 액세스 토큰을 리턴한다.
access_token
API 요청을 허가하는 데 사용되는 토큰이다.
token_type
발급된 액세스 토큰의 타입이다. 종종 'bearer'가 사용되지만 잠재적인 값들로 확장 가능하다.
이 액세스 토큰은 시간 제약이 있을 수 있기 때문에, 다음과 같은 추가 정보가 리턴될 수 있다.
expires_in
액세스 토큰이 만료되기 까지 남은 시간이다. (초 단위)
refresh_token
액세스 토큰이 만료된 후 새로운 액세스 토큰을 얻기 위해 사용되는 토큰디다.
{
"access_token" : "ya29.AHES6ZSzX",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "1/iQI98wWFfJNFWIzs5EDDrSiYewe3dFqt5vIV-9ibT9k"
}
3단계: API 호출하기
이번 단계는 사용자의 작업을 조회하고 수정한다. OAuth 2.0을 구현하는 API 제공 업체들은 전달 토큰(bearer token)을 사용한다. 이를 통해 애플리케이션이 암호화 서명 없이 요청 내에 OAuth 액세스 토큰을 포함해서 간단하게 API 요청을 허가 받을 수 있다.
## 에러처리
OAuth 2.0 액세스 토큰으로 API 호출을 만들 때, 액세스 토큰이 만료되거나 취소되어서 더 이상 유효하지 않으면 HTTP 4xx 에러가 발생한다.
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="example",
error="invalid_token",
error_description="The access token expired"
유효한 에러 코드는 invalid_request, invalid_token, insufficient_scope를 포함한다.
{
"error": {
"type": "OAuthException",
"message": "Error validating access token."
}
}
다음은 새로운 API를 요청했을 때 액세스 토큰이 만료되었다는 응답을 보여주는 구글 에제이다.
{
"error": {
"errors": [
{
"domain": "global",
"reason": "authError",
"message": "Invalid Credentials",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Invalid Credentials" }
}
4-1단계: 액세스 토큰 재발급하기
권한 코드가 액세스 토큰으로 교환될 때, API 제공 업체들은 그들의 API에 장기 오프라인 접근 모드를 지원하더라도 단기 액세스 토큰을 발급할 것이다. 비록 단기 액세스 토큰의 수명이 제한되어 있더라도, 두가지 질의 파라미터('expires_in'과 'refresh_token')를 사용하여 장기 접근이 가능하도록 응답에 포함할 수 있다.
expires_in이 응답에 포함되면 access_token의 남은 수명을 초 단위로 나타낸다. 액세스 토큰이 만료되면 refresh_token 파라미터는 새로운 액세스 토큰을 획득하는데 사용할 수 있다.
액세스 토큰 재발급은 토큰의 엔드포인트에 있는 'grant_type'을 'refresh_token'으로 설정하고, refresh_token을 포함하는 HTTP POST를 만들어 보내면 된다.
4-2단계: 새로운 액세스 토큰 획득하기
일부 애플리케이션은 사용자가 "자리에 있을 때"만 사용자의 데이터에 접근되어야 할 수도 있다. 이런 경우, 애플리케이션은 온라인(online) 접근 모드로 요청할 수 있다. 그 결과, 수명이 제한된 액세스 토큰이 발급되고 재발급 토큰은 발급되지 않는다.
구글은 기본 접근 모드가 'online'이며, 권한 코드가 요청되는 시점에 권한 엔드포인트로 'access_type=offline'이 명시적으로 전달되지 않는 한 재발급 토큰은 발급되지 않는다. 이런경우, 사용자가 "내가 애플리케이션을 사용하지 않을 때, 이 연산들을 수행하라"고 애플리케이션에 권한을 부여하면 경고가 발생한다. 온라인 접근 모드만 가진 애플리케이션이 새로운 권한 코드가 필요하다면 사용자에게 묻지 않고 클라이언트에게 자동으로 발급되고, 서버 간 호출을 통해 애플리케이션이 액세스 토큰으로 교환한다.
페이스북의 기본 접근 모드는 'online'이다. 생명주가기 제한된 액세스 토큰이 발급되고 재발급 토큰은 발급되지 않는다. 만약 애플리케이션이 오프라인 접근이 필요하면, scope 문자열에 권한에 대한 값으로 'offline_access'를 넣어서 요청하면 된다. 그러면 만료 기간이 무제한인 액세스 토큰이 발급된다. 발급된 토큰은 여전히 사용자가 접근을 취소할 수 있다.
2.5 접근을 어떻게 취소할 수 있는가?
페이스북 같은 일부 API 제공 업체들은 사용자가 비밀번호를 바꿀 때 액세스 토큰을 취소한다.
'프로그램으로 취소하기'는 OAuth 2.0 확장 스펙 초안에 정의되어 있고, 세일즈 포스와 구글처럼 대중적인 OAuth 제공 업체가 사용하고 있다. 세일즈포스는 재발급 토큰과 액세스 토큰의 취소를 허용하고, 구글은 오직 재발급 토큰의 취소만 허용하낟.
curl "https://accounts.google.com/o/oauth2/revoke?token=ya29.AHES6ZSzF
[참고 사이트]
OAUTH 2.0 - OPEN API 인증을 위한 만능 도구상자
OAuth로 OPEN API 사용하기 1) 개념 설명 및 웹 사용방법
OAuth로 OPEN API 사용하기 (v1.1a) 2) JAVA에서 라이브러리 사용
OAuth로 OPEN API 사용하기 (v2.0) 3) Facebook API 예제
OAuth2 Authentication: Log In With Facebook Account
Using OAuth 2.0 for Installed Applications
Accessing Google Services Using the OAuth 2.0 Protocol
GTM OAuth 2: Google Toolbox for Mac - OAuth 2 Controllers
Login with Google using OAuth 2.0 for iOS Xcode Objective-C
## YouTube
OAuth 2.0 Flow : Installed apps
## Line
[참고 문서]
Getting started with OAuth 2.0 - ORELLY
getting_started_with_oauth_2.0.pdf
Getting started with OAuth 2.0 - 번역서
HANB_Getting_Started_with_OAuth2.pdf
'기타' 카테고리의 다른 글
[Gradle] Gradle 기본 (0) | 2018.05.06 |
---|---|
[Java] Exception이란? (0) | 2017.08.20 |
[OSX] 시스템파일 및 숨김파일 표시 또는 숨기기 (0) | 2015.08.31 |