OAuth 2.0
OAuth의 정의와 간단한 활용법을 알아보자.
OAuth?
OAuth는 인증을 위한 오픈 스탠더드 프로토콜이다. 이렇게 읽으면 사실 별로 와닿는 설명은 아닌 것 같다. 웹 상에서 Facebook, Twitter, Google 아이디와 비밀번호를 가지고 로그인하거나 회원가입하는 경우를 많이 봤죠? 흔히 가입되어 있는 인터넷 포탈 사이트의 서비스 기능을 다른 애플리케이션(데스크톱, 웹, 모바일 등)에서 사용할 수 있도록 한 것이다.
OAuth 1.0은 2007년에 처음 등장했고, 보안 문제를 해결한 수정 버전이 2008년에 나왔다. 현재 주로 사용되고 있는 OAuth는 2.0 버전이다.
OAuth의 핵심 기능
OAuth는 유저의 요청을 통해 아이디와 비밀번호를 통해 AccessToken
을 발급해줍니다. 이 토큰은 아이디와 비밀번호 정보를 담고 있지 않으며, 제공하는 서비스의 전체 서비스가 아닌, 일부 기능만 접근할 수 있도록 제어한다는 장점이 있다.
OAuth Flow
(1) Register
Facebook for developer, Google Cloud Platform 등 OAuth 서비스 제공 페이지에서 클라이언트 서비스를 등록합니다.
- Client Id
- Client secret
- Authorized Redirect Client callback URLs (ex. https://client.com/callback)
주로 위 세가지를 등록합니다.
(2) LoginForm
흔히 우리가 알고 있는 소셜 로그인 버튼을 클릭하면 Resource Server에게 Client가 아이디, 시크릿, 요청하고자 하는 서비스(B,C), 콜백 주소와 함께 AccessToken을 요청한다.
https://resource.server/
?client_id=1
&scope=B,C
&redirect_uri=https://client.com/callback
// 예시) Google
https://accounts.google.com/o/oauth2/v2/auth?
response_type=code&redirect_uri=http://localhost:3000/auth/google/callback&scope=https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email&client_id=12341234-something9876blahblah.apps.googleusercontent.com
(3) Social Login
1) Resource Server에 로그인 여부를 확인하고, 로그인 할 수 있도록 Resource Owner에게 요청하는 페이지 화면을 띄운다.
만약 로그인이 성공하면?
2) Resource Server는 Client에서 요청한 ID값과 일치하는 값이 있는지 확인한다. 그리고 자신이 가지고 있는 Client ID 값과 요청받은 callback 주소가 일치하는지 확인한다.
3) 만약 확인해서 동일하다면, Resource Owner에게 다시 한번 요구한 특정 서비스 기능에 대한 권한을 부여하겠냐는 확인 메세지가 담긴 페이지를 보여준다. 여기서 승인 요청을 보내면 해당 Resource Server는 승인한 User의 아이디와 요청한 기능에 대한 Scope 정보를 추가로 습득한다.
(4) Resource Server Authorization
Resource Server는 Resource Owner에 대한 임시승인코드를 발급하고, Resource Owner의 웹브라우저에 Header값 Location을 담아 Client의 특정 서비스 페이지로 리다이렉트 하도록 콜백함수로 응답한다.
이제 Client는 임시승인코드 정보를 가지고 있는 상태로, Resource Server에게 직접 AccessToken 발급을 요청할 수 있다.
- Request authorization 예시
http://host1.example.com:8080/openam/oauth2/authorize?response_type=code&client_id=myClientID&redirect_uri=http://example.com/oauth
- Response 예시
HTTP/1.1 302 Found
Location: http://example.com:8080/oauth?code=7rQNrZ2CpyA8dshIJFn8SX43dAk&scope=openid%20profile&iss=http%3A%2F%2Fhost1.example.com%3A8080%2Fopenam%2Foauth2&state=af0ifjsldkj&client_id=myClientID
(5) Request Access Token
이제 Resource Server에서 임시승인코드 정보를 삭제하고, Client에 대한 Access Token 정보를 저장한다. 그리고나서 Client에게 발급한 Access Token을 전달한다!
- Request Access Token 예시
$ curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "grant_type=authorization_code&code=362ad374-735c-4f69-aa8e-bf384f8602de&redirect_uri=http://example.com/oauth&client_id=myClientID&client_secret=myClientPassword" http://host1.example.com:8080/openam/oauth2/access_token
- Response 예시
{"scope":"cn","expires_in":599,"token_type":"Bearer","refresh_token":"534310ab-570b-4eb4-0ed7-d01d243fae21","access_token":"238beab2-b545-4fee-80fa-63f224bc56f6"}
(6) API Call
이제 발급받은 Access Token을 이용해 api call을 해본다.
- API call 예시
curl -H "Authorization: Bearer <access_token> https://googleapis.com/drive/v2/files"
(7) Refresh Token
발행한 토큰은 일정 기간이 지나면 유효기간이 만료되기 때문에 주기적으로 다시 발급 요청을 보내줘야 한다.
토큰 재발급을 포함한 전체 플로우를 차트로 그려보면 다음 그림과 같다.
지금까지 OAuth의 정의와 간단한 활용법을 알아봤습니다.
OAuth의 가장 큰 매력은 신뢰할 수 있는 Server에서 사용자를 식별하는 서비스를 사용할 수 있다는 점 입니다.
오늘날에 많은 API 가 RestFul하게 만들어지고 있고, 주로 데이터 포맷이 Json, xml 형태로 사용되고 있기 때문에 이런 상황에서 OAuth를 활용해야 여러 다른 서비스에서 데이터를 불러와서 새로운 서비스에서 적절히 사용할 수 있겠죠. 스타트업을 시작하려고 한다거나 토이 프로젝트로 간단한 서비스를 만들 때 반드시 거쳐가는 관문이라고 할 수 있습니다. 이번 기회에 개념을 잘 이해하고, 앞으로 만들 서비스에서 사용해보면서 자세한 튜토리얼 포스팅도 만들어볼 예정입니다.
Reference
- 생활코딩, (Aug 03, 2020), https://opentutorials.org/course/3405
- D2Naver, (Aug 03, 2020), https://d2.naver.com/helloworld/24942
- ForgeRock, (Aug 03, 2020), https://backstage.forgerock.com/knowledge/kb/article/a45882528
- IBM Knowledge Center, (Aug 03, 2020), https://www.ibm.com/support/knowledgecenter/ko/SSFS6T/com.ibm.apic.toolkit.doc/tutorial_apionprem_security_OAuth.html
'📒 Tech Note > 웹 프로그래밍' 카테고리의 다른 글
[JS] 참고자료 모음 (0) | 2020.08.13 |
---|---|
[JS] 정규식 패턴 [xyz]과 정규식 메소드 match (0) | 2020.08.12 |
[Python] 파이썬으로 Json 인코더와 디코더 사용하기(읽고 쓰기) (3) | 2020.08.01 |
[CS] C언어의 기초 (1) (0) | 2020.08.01 |
PyPI 패키지 업로드 해보기 (0) | 2020.07.28 |