소셜로그인은 구글이나 카카오 등의 인터넷 서비스에서 사용자와 사용자가 사용하고 있는 어플리케이션 사이에서 로그인을 중개해주는 역할을 하는 것이다.
이 중개자의 역할을 가능하도록 해주는 서비스가 "OAuth" 이다.
- OAuth는 인증을 위한 오픈 스탠더드 프로토콜로, 사용자가 Facebook이나 트위터 같은 인터넷 서비스의 기능을 다른 애플리케이션(데스크톱, 웹, 모바일 등)에서도 사용할 수 있게 한 것이다.
- 사용자들이 해당 애플리케이션에 사용자의 아이디와 암호를 제공하지 않고 다른 웹사이트 상의 자신들의 정보에 대해 해당 애플리케이션에 접근 권한을 부여할 수 있는 공통적인 수단으로서 사용되는, 접근 위임을 위한 개방형 표준이다.
OAuth에서 'Auth' = 'Authentication'(인증)+ 'Authorization'(허가)
'Authentication' : 외부 어플리케이션(나의 서비스)는 사용자 인증을 위해 Facebook과 Apple 및 Google의 등의 사용자 인증 방식을 사용한다.
'Authorization' : 이 때, OAuth를 바탕으로 사용자가 이용하고자 하는 제 3 서비스(나의 서비스)는 외부 서비스(Facebook, Apple, Google)의 특정 자원을 접근 및 사용할 수 있는 권한을 인가받게 된다.
ex. 나의 서비스가 facebook 소셜 로그인을 이용 -> 사용자가 facebook에 로그인 -> facebook에서 사용자를 인증 -> 사용자는 facebook에 나의 서비스가 사용자의 facebook내의 정보를 사용해도 된다는 것을 허가
=> facebook에서는 해당 사용자를 인증 + facebook에 있는 사용자의 정보를 제공
사용자의 암호화 아이디를 관리하지 않고, 소셜 서비스를 이용해 사용자를 인증할 수 있다는 편리함과 단순 로그인 기능을 넘어서, 소셜 서비스에 있는 사용자의 정보를 나의 애플리케이션이 접근/사용할 수 있도록 허가를 받는 것이 포함됨!
OAuth 동작에 관여하는 참여자는 크게 세 가지로 구분할 수 있다.
Client(웹 어플리케이션)가 Resource Server를 이용하기 위해서는 자신의 서비스를 등록함으로써 사전 승인을 받아야 한다.
Github Developer Settings에 나의 서비스를 등록한다고 가정하자.

Authorized redirect URL : Authorization Code를 전달받을 리다이렉트 주소.

Client ID : 클라이언트 웹 어플리케이션을 구별할 수 있는 식별자이며, 노출이 무방.
Client Secret : Client ID에 대한 비밀키로서, 절대 노출해서는 안됨.
client는 소셜 로그인을 위해 다음과 같은 url로 Get요청을 보냄.
GET https://github.com/login/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}?scope={scope}
사용자에게 다음과 같은 화면으로 redirect됨.

소셜 서비스에 대한 로그인이 완료되면 Resource Server는 Query String으로 넘어온 파라미터들을 통해 Client를 검사.
https://github.com/login/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}?scope={scope}
2.3단계에서 Resource Server가 요청을 보낸 client에 대해 검사를 마쳤다면, Resource Server는 Resource Owner에게 다음과 같은 질의를 보낸다.
명시한 scope에 해당하는 권한을 Client에게 정말로 부여할 것인가?

Resource Owner의 승인이 마무리 되면 명시된 Redirect URL로 클라이언트를 리다이렉트 시킨다. 이 때 Resource Server는 Client가 자신의 자원을 사용할 수 있는 Access Token을 발급하기 전에, 임시 암호인 Authorization Code를 함께 발급한다.

Client는 CLIENT ID, SECRET KEY, Authorization Code를 Resource Server에 직접 전달한다. Resource Server는 정보를 검사한 다음,
유효한 요청이라면 Access Token + Refresh Token을 발급해준다.
Cient는 해당 토큰을 서버에 저장해둔다. 또한 Resource Server의 자원을 사용하기 위한 API 호출시 해당 토큰을 헤더에 담아 보낸다.
access token의 만료 기간이 Resfresh Token보다 짧다.
정리하자면!
1. 클라이언트 쪽에서 로그인을 한다(카카오에 api 요청)
2. 카카오 서버는 redirect url로 code를 전달해준다
@ResponseBody
@GetMapping("/kakao")
public void kakaoCallback(@RequestParam String code) throws BaseException {
System.out.println(code);
}
-> redirect url에 parameter로 전달된 code를 controller영역에서 받아온다.
3 code를 이용하여 access_token을 발급받는다
4. access_token을 서버로 전송한다
5. 서버에서는 받은 access_token을 이용하여 카카오 서버에서 사용자 정보를 받는다
6. 받은 사용자 정보를 이용하여 회원가입 또는 로그인을 진행한다
7. JWT등과 같이 사용자 식별 정보를 클라이언트로 보낸다