개념부터 잡고 넘어가보자.
OAuth 2.0 is the industry-standard protocol for authorization.
OAuth의 공식 레퍼런스 사이트에서는 위와 같이 말하고 있다.
한 마디로, 인증을 위한 개방형 표준 프로토콜이다.
OAuth가 나오기 전에는 여러 서비스사에서 각자 개발한 방식대로 인증을 진행했다.
이런 여러 인증 방식을 표준화 한 것이 OAuth이다.
OAuth를 사용하면 해당 인증을 공유하는 어플리케이션끼리는 추가적인 인증이 필요없다.
그런데 OAuth 2.0이라면 1.0도 있나? 있다. 그런데 공식적으로 2.0을 쓰라고 권하고 있다.
Why?
1.0은 사장된 기술이니 이쯤에서 접고, OAuth 2.0에 대해 조금 더 알아보자.
OAuth 2.0 의 구성 역할은 4가지이다.
RFC6749에 따르면 기본적인 흐름은 아래와 같다.
A의 인증 요청은 Client가 User에게 직접적으로 할 수도 있지만, 설게에 따라 Authorization Server를 통해 간접적으로 요청할 수도 있다.
위 과정에서 Authorization Grant라는 부분은 여러가지 방법으로 수행될 수 있다.
response_type=code
Authorization Code를 이용해 인증을 수행하는 방식이다. 간편 로그인 기능 등 타사의 클라이언트에게 보호된 자원을 제공할 때 많이 사용한다. 이 방법은 가장 기본적인 방법이고, 특징적인 장점이 하나 있다. 이 방법은 프론트단에는 Authorization Code만을 넘기고 Access token은 넘기지 않는다. 이를 통해 보안을 향상 시킬 수 있다. 또한 Refresh token의 사용이 가능한 방법이다.
다른 방식들과 다르게 access token을 얻기 위한 요청을 한 번 더 보내야 한다.
해당 요청을 위한 패러미터 값의 규격이 있는데,
grant_type=authorization_code // 필수
code=받은코드 // 필수
redirect_uri=조건부로 필요
client_id=조건부로 필요
위와 같이 보내면 된다.
response_type=token
Authorization code를 이용한 방식의 간소화 버전이다. JS를 사용한 SPA 등 자격증명을 안전하게 보관하기 힘든 클라이언트가 많이 사용한다. 많은 경우 Redirection URI를 이용해 access token을 발급한다. 이 경우, resource owner나 resource owner의 user-agent에 접근 가능한 어플리케이션들에 access token이 노출된다. 그렇기에 보안이 취약하고, 공식 문서에도 authorization code를 이용한 방식이 사용 가능한 경우 Implicit 방식 사용을 지양할 것을 권하고 있다.
더불어 이 방식의 경우 refresh_token은 발급되지 않는다.
grant_type=password
간단히 말해, User가 Authorization Server를 통해 직접적인 인증을 하는 것이 아니라, Client에 id, password를 제공하고 client가 대리인증을 하는 방식이다.
Id, password를 넘긴다는 것에서 바로 느낄 수 있지만, 타사의 클라이언트를 통한 인증 시에 제공할 만한 방법이 아니다. 해당 방법의 사용 예시는 카카오 페이에 카카오톡 ID를 이용한 인증 등이 있겠다. 해당 경우, Client와 Authorization Server, Resource Server가 모두 카카오 소속이니 믿고 사용할 수 있다. 물론 카카오 페이에서 실제로 이 방식으로 인증을 했는지 어떤지는 모른다.
grant_type=client_credentails
Client의 자격증명만으로 access token을 얻는 방식이다. Authorization Server와 Resource Server에 해당 Client를 위한 제한된 리소스 접근 권한이 설정되어 있는 경우 사용 가능하다. 이 방식의 경우 Refresh Token은 굳이 원한다면 사용 가능하지만 권장되지 않는다.
인증 방식은 아닌데, access token 만료 시에 refresh token을 사용해 재발급을 받는 요청이 따로 있다.
grant_type=refresh_token
refresh_token=리프레쉬 토큰
을 요청에 포함해 보내줘야 한다.
Parameter | Description |
---|---|
client_id, client_secret | client용 자격증명. 인증 서버에 등록된 client라면 받을 수 있으며 인증 시 client의 검증에 사용된다 |
redirect_url | 인증 서버가 응답을 보낼 url |
response_type | 2가지가 있다. code와 token. 각각 Authorization Code Grant 방식과 Implicit Grant 방식에 사용된다 |
state | CSRF 공격 대비용 항목이다. 클라이언트가 임의로 만들어낸 문자열이며, 요청에 이 항목이 있었다면 인증 서버는 응답에 해당 항목을 똑같이 포함시켜 보내줘야한다 |
grant_type | access token 요청 시 사용되는 항목이다. 값으로는 authorization_code, password, client_credentials, refresh token이 있다. |
code | Authorization Code Grant 방식 사용 시 access token 발급용 요청에 들어가는 항목이다. 받은 코드를 넣어주면 된다 |
token_type | 발행된 token의 타입이다. Bearer, MAC 등이 있다 |
expires_in | token의 TTL |
example_parameter | token type에 따른 추가적인 항목이다 |
API 요청은 Authorization 헤더가 포함되어야 하며 client_id와 client_secret의 복합적인 값을 기반으로 생성된다. base64(client_id:client_secret)
와 같은 형식으로 인코딩 해주면 된다. 인코딩 된 값에 prefix로 Basic을 붙여 Basic 코드
의 형식으로 넣어주자.