OAuth는 외부서비스(third-party application)으로 구글, 페이스북 등의 인증 및 권한부여를 관리하는 범용 프레임워크.
OAuth에서 주체는 Client, Resource Owner, Server(Resource Server, Authorization Server)로 3명
client : 서비스를 운영하는 측(확장 기능을 이용하고자 하는 서버)
Resource owner : 애플리케이션을 이용하는 유저
Server(Resource server, Authorization Server) : 각각 데이터를 가지고있는 서버, 인증 권한을 전담하는 서버
OAuth 목적은 Access Token을 획득하기 위함이다.
OAuth 클라이언트가 리소스 서버에 등록하기 위한 필수 요소는 클라이언트ID, Secret Key, redirect URL 3가지이다.
상세 사용 절차(위 사진의 순서와 관계 없음)
간략하게 Resource Owner = Owner, Resource Server = Server로 작성한다.
ex) 운영하는 클라이언트 서버에서 구글 캘린더 , 페이스북 등에 접근하려고 할때
1. 우선 서비스를 운영하는 Client는 Server(페이스북, 구글 등)에 등록을 한다.
2. 등록을 하면 Serve로 부터 client id, secret key, redirect url을 발급받게 된다.
3. Client는 Serve로 부터 받은 정보를 토대로 해당 연동 위치에 링크를 걸어준다.
4. Owner는 Client가 걸어둔 링크를 통해 id값, 권한, redirect url을 Server에 요청 보낸다.
5. Server는 Owner가 로그인이 되어있는지 확인한 후 안되있을 경우 로그인 창을 띄워준다.
6. Server는 Owner로 부터 받은 값에서 client id와 redirect url의 정보가 맞는지 확인한다.
7. 정보가 일치하면 Server는 Owner에게 authorization code를 주고 Client로 리다이렉션 시킨다.
8. Client는 Owner에 있는 authorization code를 저장하고 Server에게 id, key, url, code를 모두 전송한다.
9. Server은 Client로 부터 받은 정보와 Owner에게 부여했던 code값 들을 모두 비교하고 일치하는지 확인한다.
10. 정보가 모두 일치하면 Server은 Client에게 Access Token을 발급하고 authorization code값을 지운다.
최종적으로 리소스 서버로부터 클라이언트가 access token을 받으면 이를 이용해 API를 호출 할 수 있다.
호출 방법으로는 url 파라미터로 토큰을 입력하는 방법과 Authorization: Bearer을 HTTP header로 전송하는 방법이 있는데, Authorization: Bearer을 HTTP header로 전송하는 방법이 더 안전하고 표준화 되어있다.
access token에는 유효기간이 있으며, 유효기간이 만료 되었을 때 refresh token으로 다시 갱신할 수 있다.
refresh token은 보통 access token과 같이 발급된다.
OAuth 프레임워크에서 발생하는 산출물 Token의 한 형식인 JWT.
OAuth token은 어떠한 사용자인지에 대한 명확한 정보를 가지고 있지 않는 반면에 JWT는 명확한 정보를 가지고 있다.
JWT는 전자 서명된 URL-safe(URL로 이용할 수 있는 문자로만 구성된)의 JSON이다.
https://console.cloud.google.com/
클라이언트에서 서버에 등록하기 위해 위의 사이트로 접속해서 사용하려는 API를 검색한다.
구글 캘린더를 사용하기 위해 검색을하고 사용 클릭
이후 사용자 인증 정보(OAuth ID)를 만들고 OAuth 동의 화면 등을 입력한다.
이때 승인된 리다이렉션 URI는 인증 후 넘어올 클라이언트의 URI를 입력하면 된다.
입력을 전부 완료하면 서버로 부터 클라이언트ID(client_id), 클라이언트 비밀번호(secret_key)가 발급된다.
https://developers.google.com/identity/protocols/oauth2/web-server#httprest_1
위의 API 문서를 참고하여 구글 서버로 부터 등록 후 받은 값들을 넣어준다.
//index.html
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Page Title</title>
</head>
<body>
<a href="">로그인</a>
</body>
</html>
// a 태그 안에 링크로 들어갈 내용
https://accounts.google.com/o/oauth2/v2/auth?
scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
access_type=offline&
include_granted_scopes=true&
response_type=code&
state=state_parameter_passthrough_value&
redirect_uri=https%3A//oauth2.example.com/code&
client_id=client_id
scope에는 접근할 값을 넣어준다.(ex. 캘린더 목록)
redirect_uri에는 서버에 등록했던 값을 동일하게 넣어주고,
client_id는 서버로부터 받은 값을 넣어준다.
이때 위의 값들은 인코딩해서 넣을 것
위와 같이 했을때, a태그로 감싸져 있는 로그인을 누르면 구글 계정에 로그인 하라는 창이 뜨고 scope에 접근할 값에 대한 동의 요청을 받는다.
동의를 하면 설정한 redirect_uri로 페이지가 전환되며 서버로부터 authorizaztion_code값을 받게 된다.
//redirect.html
<html>
<body>
<a href="/index.html">메인가기</a>
<form action="https://www.googleapis.com/oauth2/v4/token" method="post" enctype="application/x-www-form-urlencoded">
code : <input type="text" name="code" value=""/><br/>
client_id : <input type="text" name="client_id" value=""/><br/>
client_secret : <input type="text" name="client_secret" value=""/><br/>
redirect_uri : <input type="text" name="redirect_uri" value="http://localhost:5500/redirect.html"/><br/>
grant_type : <input type="text" name="grant_type" value="authorization_code"/><br/>
<input type="submit" />
</form>
</body>
</html>
서버로 부터 받은 authorizaztion_code의 값을 redirect.html에서 code 값으로 넣어주고 client_id, client_secret, redirect_uri 정보를 모두 넣어주고 submit하면 최종적으로 서버로부터 access_token을 발급 받는다.
※ 참 고
위의 결과를 보면 refresh_token도 있는데 index.html에서 access_type부분을 offline으로 했을 때 받는 값으로 access_token이 만료 되었을때 refresh_token을 이용해 재발급 받을 수 있다.
이후 발급받은 access token으로 api를 사용할 수 있다.
구글 캘린더 목록을 조회하려면
1. url 파라미터 방식
https://www.googleapis.com/calendar/v3/users/me/calendarList?access_token=토근값
2. Authorization: Bearer 방식(cmd)
curl -H "Authorization: Bearer 토큰값" https://www.googleapis.com/calendar/v3/users/me/calendarList
OAuth 2.0, Grant Type 개념 정리 링크
https://jsonobject.tistory.com/369
애자일 소프트웨어 개발 선언 (0) | 2021.07.29 |
---|---|
스프링 핵심 원리 (0) | 2021.07.29 |
기술면접 (0) | 2021.05.04 |
clean code 3가지 사항 (0) | 2021.04.29 |
[1차-환경구축]Spring-boot/JPA/H2(로그인, 게시판) (0) | 2021.04.26 |