1) Oauth란?
- 특정 사이트를 이용하려고 하면 SNS 로그인과 같은 기능이 있습니다. 이러한 SNS 로그인 기능을 제공하는데 사용되는 기반 프로토콜을 Oauth라고 합니다.
2) Oauth의 정의
- 위키백과에 따르면 Oauth의 정의는 다음과 같습니다.
Oauth는 인터넷 사용자들이 비밀번호를 제공하지 않고, 다른 웹사이트 상의 자신들의 정보에 대해 웹사이트나 애플리케이션의 접근 권한을 부여할 수 있는
공통적인 수단으로서 사용되는
접근 위임을 위한 개방형 표준이다.
예를 들어, 망고플레이트와 같은 어플리케이션은 사용자 인증을 위해 페이스북, 카카오톡, 애플의 사용자 인증 방식을 사용합니다. 이 때, 망고플레이트는 Oauth를 바탕으로 외부 서비스(페이스북, 카카오톡, 애플)의 자원에 접근할 수 있는 권한을 인가받습니다.

2. Oauth 참여자
- Oauth 동작에 관여하는 참여자는 크게 세 그룹으로 나눌 수 있습니다.
(1) Resource server
- Client가 제어하고자 하는 자원을 보유하고 있는 서버입니다. ex) Facebook, Google, Twitter
(2) Resource Owner
- 자원의 소유자입니다. 즉, Client가 제공하는 서비스를 통해 로그인하는 실제 유저입니다.
(3) Client
- Resource Server에 접속해서 정보를 가져오고자 하는 클라이언트(웹 애플리케이션)입니다.
3) Oauth flow
- 간단한 웹 애플리케이션 제작을 통해 Oauth의 동작 프로세스를 이해해볼 수 있습니다.
Github 계정을 바탕으로 웹 어플리케이션에 로그인하고,
Github에서 제공하는 여러 API를 외부 어플리케이션에서 사용해보겠습니다.
3-1) Client 등록
- Client가 Resourse Server를 사용하기 위해서는 자신의 서비스를 사전 등록해서 승인을 받아야 합니다.
Github Developers Settings에서 Github에 웹 애플리케이션을 등록합니다.


- 등록 절차를 통해 세 가지 정보를 부여 받습니다.
1. Client ID
- 클라이언트 웹 어플리케이션을 식별할 수 있는 식별자이며, 노출이 되어도 상관 없습니다.
2. Client Secret
- Client ID에 대한 비밀값으로써, 노출이 되어서는 안됩니다.
3. Authorized Redirect URL
- Authorization Code를 전달 받을 URL입니다.
- 외부 서비스를 통해 인증을 마치면 클라이언트를 명시된 주소로 리다이렉트시키며,
이 때, Query String으로 특별한 코드가 같이 전달됩니다.
Client가 해당 Code와 Client ID, Client Secret을 Resource Server에 보내면,
Resource Server의 자원을 사용할 수 있는 Access Token을 발급 받을 수 있습니다.
3-2) Resource Owner의 승인
- Github Docs에서는 Github 소셜 로그인을 하기 위해 다음과 같은 주소로
GET 요청과 필요한 파라미터들을 보내도록 명시합니다.
GET https://github.com/login/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}?scope={scope}
- scope는 Client가 Resource Server로부터 인가를 받을 권한의 범위입니다.
- 파라미터의 세부 옵션에 관한 내용은 문서를 참고하면 확인할 수 있습니다.
- Resource Owner는 Client의 웹 애플리케이션을 이용하다가,
해당 주소로 연결되는 소셜 로그인 버튼을 클릭합니다.

- Resource Owner는 Resource Server에 접속해서 로그인을 수행합니다. 로그인이 완료되면
Resource Server는 Query String으로 넘어온 파라미터들을 통해 Client를 검사합니다.
(1) 파라미터로 전달된 Client ID와 동일한 ID값이 존재하는지 확인합니다.
(2) 해당 Client ID에 해당하는 Redirect URL이 파라미터로 전달된 Redirect URL과 같은지 확인합니다.

- 검증이 마무리 되면 Resource Server는 Resource Owner에게 다음과 같은 질의를 보냅니다.
-> 명시한 Scope에 해당하는 권한을 Client에게 정말 부여할 것인가?
-> 허용한다면 최종적으로 Resource Owner가 Resource Server에게 클라이언트의 접근을 승인하게 됩니다.
3.3 Resource Server의 승인
- Resource Owner의 승인이 마무리 되면, 명시된 Redirect URL로 클라이언트를 리다이렉트 시킵니다.
이 때, Resource Server는 Client가 자신의 자원을 사용할 수 있는 Access Token을 발급하기 전에
임시 암호인 Authorization Code를 같이 발급합니다.

- Query String으로 들어온 코드가 바로 Authorization Code입니다.
[OAuthController.java]
@GetMapping("/afterlogin")
public ResponseEntity<String> afterlogin(@RequestParam String code) {
if (Objects.isNull(code)) {
throw new IllegalStateException("Github 로그인이 실패했습니다.");
}
RestTemplate restTemplate = new RestTemplate();
OauthDto oauthDto = new OauthDto();
oauthDto.setCode(code);
oauthDto.setClient_ID("7e930566ecaa306c71b5");
oauthDto.setClient_secret("client secret 입력");
String accessToken = restTemplate.postForObject("https://github.com/login/oauth/access_token", oauthDto, String.class);
return ResponseEntity.ok(accessToken);
}
- Client는 ID와 비밀키 및 코드를 Resource Owner를 거치지 않고, Resource Server에 직접 전달합니다.
Resource Server는 정보를 검사한 다음, 유효한 요청이라면 Access Token을 발급합니다.

- Client는 해당 토큰을 서버에 저장해두고, Resource Server의 자원을 사용하기 위한 API 호출 시 헤더에 토큰을
담아 보냅니다.
3.4 API 호출

- 이후 Access Token을 헤더에 담아 Github API를 호출하면 해당 계정과 연동된 Resource Server의 풍부한 자원과 기능들을 내가 만든 웹 애플리케이션에서 사용할 수 있습니다.
3.5 Refresh Token
- Access Token은 만료 기간이 있으며, 만료된 Access Token으로 API를 요청하면 401 에러가 발생합니다.
Access Token이 만료 되어 재발급받을때마다, 서비스 이용자가 재로그인 하는 것은 다소 번거롭습니다.
- 보통 Resource Server는 Access Token을 발급할 때, Refresh Token을 함께 발급합니다.
Client는 두 토큰을 모두 저장해두고, Resource Server의 API를 호출할 때는 Access Token을 사용합니다.
Access Token이 만료되어 401 에러가 발생하면, Client는 보관중이던 Refresh Token을 보내
새로운 Access Token을 발급 받습니다.
- 참고
https://tecoble.techcourse.co.kr/post/2021-07-10-understanding-oauth/
'네트워크' 카테고리의 다른 글
| HTTP (0) | 2022.09.21 |
|---|---|
| OSI 7계층과 TCP/IP 4계층을 비교하여 설명하기 (1) | 2022.09.19 |
| OSI 7계층 - 데이터 링크 계층 (0) | 2022.09.01 |
| OSI 7계층 - 물리 계층 (0) | 2022.08.31 |
| Restful 설계 원칙 (0) | 2022.08.26 |