OAuth란?
웹을 사용하다 보면 Google과 Facebook 등의 외부 소셜 계정을 기반으로 간편히 회원가입 및 로그인할 수 있는 웹 어플리케이션을 쉽게 찾아볼 수 있다.
클릭 한 번으로 간편하게 로그인할 수 있을 뿐만 아니라, 연동되는 외부 웹 어플리케이션에서 Facebook 및 Twitter 등이 제공하는 기능을 간편하게 사용할 수 있다는 장점이 있다.
예를 들어, Google로 로그인하면 API를 통해 연동된 계정의 Google Calendar 정보를 가져와 사용자에게 보여줄 수 있다.
이 때 사용되는 프로토콜이 바로 OAuth다.
OAuth에 대한 정의는 다음과 같다.
OAuth는 인터넷 사용자들이 비밀번호를 제공하지 않고 다른 웹사이트 상의 자신들의 정보에 대해 웹사이트나 애플리케이션의 접근 권한을 부여할 수 있는 공통적인 수단으로서 사용되는, 접근 위임을 위한 개방형 표준이다.
※ 참고
OAuth 2.0은 1.0에서 알려진 보안 문제 등을 개선한 버젼이다.
OAuth 구성 요소
구분 | 설명 |
Resource Owner | 웹 서비스를 이용하려는 유저, 자원(개인정보)을 소유하는 자, 사용자 'Resource' 는 개인정보라고 생각하면 된다. |
Client | 자사 또는 개인이 만든 애플리케이션 서버 클라이언트 라는 이름은 Client가 Resource server에게 필요한 자원을 요청하고 응답하는 관계여서 그렇다. |
Authorization Server | 권한을 부여(인증에 사용할 아이템을 제공주는)해주는 서버다. 사용자는 이 서버로 ID, PW를 넘겨 Authorization Code를 발급 받을 수 있다. Client는 이 서버로 Authorization Code을 넘겨 Token을 받급 받을 수 있다. |
Resource Server | 사용자의 개인정보를 가지고있는 애플리케이션 (Google, Facebook, Kakao 등) 회사 서버 Client는 Token을 이 서버로 넘겨 개인정보를 응답 받을 수 있다. |
Access Token | 자원에 대한 접근 권한을 Resource Owner가 인가하였음을 나타내는 자격증명 |
Refresh Token | Client는 Authorization Server로 부터 access token(비교적 짧은 만료기간을 가짐) 과 refresh token(비교적 긴 만료기간을 가짐)을 함께 부여 받는다. access token은 보안상 만료기간이 짧기 때문에 얼마 지나지 않아 만료되면 사용자는 로그인을 다시 시도해야한다. 그러나 refresh token이 있다면 access token이 만료될 때 refresh token을 통해 access token을 재발급 받아 재 로그인 할 필요없게끔 한다. |
직접 사용자가 로그인 하는것이 아닌, 소셜 미디어로 로그인을 할 경우, client(개인 서비스)는 Resource Owner(사용자)를 대신해 로그인 하는데, 이때 필요한 정보를 Resource Server(kakao, naver, ...)에서 얻어 서로 비교해 유효성을 판단한다.
client가 유저의 (로그인)정보/자원(resource)을 Resource Server에 요청해 대신 로그인 하는 것이다.
이를 위해서 client는 다음 단계들을 가진다.
- Resource Owner로 부터 동의(허용)
- Resource Server로 부터 client 신원확인
왜 그래야 할까?
각각의 입장에서 생각해보자.
Resource Owner(유저) 입장
자신의 정보를 대신 사용하기 때문에 client가 어떤 정보를 활용하는지, 어떤 기능을 사용하려는지 모른다.
나쁜 마음을 가지면 개인정보를 마구잡이로 악용할수 있을 수도 있기 때문이다.
그러므로 client는 Resource Owner의 동의를 구해야 한다.
Resource Server(kakao) 입장
다른 사람의 일을 대신 해주는 사람이 정말 그 사람일지 궁금할 수 있다.
마찬가지로 Resource Owner의 일을 수행 해주는 client가 정말 그 client일까 하는 물음이 있다.
이런 의미에서 Resource Server는 Resource Owner의 브라우저를 통해 client를 구분하는 값(code)를 전달한다.
OAuth 서비스 등록해보기 (네이버 로그인)
callbackURL 및 네이버로 요청할 정보(scope) 설정하기
등록을 완료하면 해당 클라이언트 아이디와 비번 정보가 나온다.
Client ID, Client Secret , Authorized redirect URIs는 서비스를 등록하면 받게 되는 필수 요소로 특징은 다음과 같다.
Client ID
- 어플리케이션(서비스)을 식별하는 식별자ID를 의미한다.
- 다양한 서비스가 존재하는데, Resource Server 입장에서 어떤 서비스에게 제공할 것 인지 구분하는 ID를 의미한다.
Client Secret
- Client ID에 대한 비밀번호로 외부에 노출되면 안된다.
- ID의 PASSWORD라고 생각하면 된다.
- Resource Server만 갖는 정보로, client에 권한을 부여하는 과정에서 나중에 Authorized code를 전달하는 통로다.
- 나중에 client <-> Resource Server 유효성 검사에서 이 redirect URIs도 체크되며 해당주소가 아닐 경우 Resource Server는 해당 client가 아니라고 판단한다.
- 즉, 예를들어 네이버 서버가 사용자의 개인정보를 콜백할 주소를 적는 곳이다.
scope
- Resource Server에서 사전에 사용 가능하도록 미리 정의한 기능
- 글 작성하기, ID알기, Email 알기, 캘린더 일정 입력하기 등등
- 페이스북이든 구글이든 로그인 되었다면, 그 서비스 안에서 사용할 수 있는 모든 기능
Resource owner 승인과정
아래에선 이해를 좀더 쉽게 돕기 위해 Resource Server와 Authorization Server을 합쳐서 설명.
1. 사용자(Resource Owner)는 서비스(client)를 이용하기 위해 로그인 페이지에 접근한다.
2. 그럼 서비스(client)는 사용자(Resource Owner)에게 로그인 페이지를 제공하게 된다. 로그인 페이지에서 사용자는 "페이스북/구글 으로 로그인" 버튼을 누른다.
3. 만일 사용자가 Login with Facebook 버튼을 클릭하게 되면, 특정한 url 이 페이스북 서버쪽으로 보내지게 된다.
브라우저 응답(response) 헤더를 확인하면 다음 url내용을 확인 할 수 있다.
https://resource.server/?client_id=1&scope=B,C&redirect_uri=https://client/callback
이는, 사용자가 직접 페이스북으로 이동해서 로그인을 입력해야 하는데, 저 링크가 대신 로그인으로 이동 하게끔 도와준다.
구체적으로 위의 코드가 어떻게 구성되어 있는지 알아보자
코드를 나누어 설명해보자면,
https://resource.server/? # 리소스 서버(네이버, 카카오 사이트 url)
client_id=1 # 어떤 client인지를 id를 통해 Resouce Owner에게 알려주는 부분
&scope=B,C # Resource Owner가 사용하려는 기능, 달리 말해 client가 자신 서비스에서 사용하려는 Resource Server 기능을 표현한 부분
&redirect_uri=https://client/callback # 개발자 홈페이지에 서비스 개발자가 입력한 응답 콜백.
향후 redirect_uri 경로를 통해서 Resource Server는 client에게 임시비밀번호인 Authorization code를 제공한다.
4. 클라이언트로부터 보낸 서비스 정보와, 리소스 로그인 서버에 등록된 서비스 정보를 비교한다.
4.1 확인이 완료되면, Resource Server로 부터 전용 로그인 페이지로 이동하여 사용자에게 보여준다.
5. ID/PW를 적어서 로그인을 하게되면, client가 사용하려는 기능(scope)에 대해 Resource Owner의 동의(승인)을 요청한다.
※ 참고
위 이미지의 의미는 다음과 같다.
"c9users.io라는 client(서비스,application)는 Resoure Owner를 대신해 해당 기능(scope)를 사용하려고 합니다.동의하시겠습니까?"
동의(Allow)를 누르는 것은 Resoure Owner는 Client가 해당 기능 사용에 위임(delegation)했다를 의미한다.
5.1 Resource Owner가 Allow 버튼을 누르면 Resource Owner가 권한을 위임했다는 승인이 Resource Server 에 전달된다.
이로써 Resource Sever가 갖는 정보는 다음과 같다.
- Client Id : Resource Owner와 연결된 client가 누군지
- Client Secret: Resource Owner와 연결된 client의 비밀번호
- Redirect URL : (진짜)client와 통신할 통로
- user id : client와 연결된 Resource Owner의 id
- scope : client가 Resource Owner 대신에 사용할 기능들
6. 하지만, 이미 Owner가 Client에게 권한 승인을 했더라도 아직 Server가 허락하지 않았다. 따라서, Resource Server 도 Client에게 권한 승인을 하기위해 Authorization code를 Redirect URL을 통해 사용자에게 응답하고
7. 다시 사용자는 그대로 Client에게 다시 보낸다.
8. 이제 Client가 Resource Server에게 직접 url(클라이언드 아이디, 비번, 인증코드 ...등)을 보낸다.
9. 그럼 Resource Server는 Client가 전달한 정보들을 비교해서 일치한다면, Access Token을 발급한다. 그리고 이제 필요없어진 Authorization code는 지운다.
10. 그렇게 토큰을 받은 Client는 사용자에게 최종적으로 로그인이 완료되었다고 응답한다.
※ 참고
OAuth의 목적은 최종적으로 Access Token을 발급하는 것이다.
11 ~ 14. 이제 client는 Resource server의 api를 요청해 Resource Owner의 ID 혹은 프로필 정보를 사용할 수 있다.
15. Access Token이 기간이 만료되어 401에러가 나면, Refresh Token을 통해 Access Token을 재발급 한다.
※ 참고
Refresh Token
Refresh Token의 발급 여부와 방법 및 갱신 주기 등은 OAuth를 제공하는 Resource Server마다 상이하다.
Access Token은 만료 기간이 있으며, 만료된 Access Token으로 API를 요청하면 401 에러가 발생한다.
Access Token이 만료되어 재발급받을 때마다 서비스 이용자가 재 로그인하는 것은 다소 번거로울 것이다.
보통 Resource Server는 Access Token을 발급할 때 Refresh Token을 함께 발급한다.Client는 두 Token을 모두 저장해두고, Resource Server의 API를 호출할 때는 Access Token을 사용한다.
Access Token이 만료되어 401 에러가 발생하면, Client는 보관 중이던 Refresh Token을 보내 새로운 Access Token을 발급받게 되어 로그인 인증을 유지 할 수 있게 된다.
참고