✏️ 공부 내용
1학기 Final 관통을 진행하면서 OAuth2.0을 활용한 로그인 구현을 맡게 되었다.
초반에는 Spring Security를 사용하지 않고 구현하였다가 이후에 Spring Security를 적용하였는데 해당 과정에서 기존 코드와 달라진게 많아 정리해보았다.
배경
네이버, 구글, 카카오,... 중에 카카오 연동 로그인을 구현하였다.
Spring Security를 사용하지 않은 경우, redirect uri를 프론트로 지정하였고
Spring Security를 사용한 경우, redirect uri를 백으로 지정하였다.
OAuth2.0 (w/o Spring Security)
과정
1. Service Client가 로그인 요청을 한다.
2. Service Server가 yml 파일에 저장된 내용을 이용해 Authorization URI를 생성하여 Service Client에게 전달한다.
3. Service Client가 axios로 Auth Server에게 GET 요청을 보낸다.
4. Auth Server가 Service Client에게 로그인 페이지를 제공하며 ID와 PW를 요청한다.
5. Service Client가 로그인한다.
6. Auth Server가 Service Client에게 정보제공 동의 화면을 출력한다.
7. Service Client가 동의 및 계속하기를 선택한다.
8. Auth Server가 Service Client에게 Authorization Code를 전달한다.
9. Service Client는 Service Server에게 Authorization Code를 전달하며 token을 요청한다.
10. Service Server는 전달받은 Authorization Code와 yml에 저장된 정보들(client_id, client_secret 등)을 활용하여 Auth Server에게 token을 요청한다.
11. Auth Server가 Service Server에게 token을 전달한다
12. Auth Server로부터 전달받은 token을 이용하여 Service Server가 Auth Server에게 사용자 정보를 요청한다.
- 사용자가 유효한 계정을 가지고 로그인했는지만 필요하기 때문에 Auth Server로부터 전달받은 token은 Auth Server에게 사용자 정보를 요청할 때만 사용하고 실제 서비스 진행 과정에서는 직접 만든 access token과 refresh token을 사용한다.
13. Auth Server가 Service Server에게 사용자 정보를 전달한다.
14. Auth Server로부터 전달받은 사용자 정보를 이용하여 access token과 refresh token을 생성하여 Service Client에게 해당 token들을 전달한다. 이때, token들을 쿠키에 담아서 전달한다.
- 초기에는 token을 body에 담았지만 Spring Security를 적용하면서 쿠키에 담아 전달하도록 변경하였다.
- 변경 이유는 본문 아래에 자세히 작성
15. Service Client가 사용자 정보가 필요한 경우, Service Server에게 해당 정보를 요청한다.
16. Service Server가 쿠키에 담긴 access token을 디코딩하여 access token에 담긴 사용한 사용자 정보를 Service Client에게 전달한다.
OAuth2.0 (w/ Spring Security)
1. Service Client가 로그인 요청을 한다.
2. Service Server가 yml 파일에 저장된 내용을 이용해 Authorization URI를 생성하여 Auth Server에게 GET 요청을 보낸다.
3. Auth Server가 Service Client에게 로그인 페이지를 제공하며 ID와 PW를 요청한다.
4. Service Client가 로그인한다.
5. Auth Server가 Service Client에게 정보제공 동의 화면을 출력한다.
6. Service Client가 동의 및 계속하기를 선택한다.
7. Auth Server가 Service Client에게 Authorization Code를 전달한다.
8. Service Client는 Service Server로 redirect한다.
9. Service Server는 Auth Server에게 token을 요청한다.
10. Auth Server는 Service Server에게 token을 전달한다.
11. Service Server는 Auth Server에게 사용자 정보를 요청한다.
12. Auth Server는 Service Server에게 사용자 정보를 전달한다.
13. Service Server는 Auth Server로부터 전달받은 사용자 정보를 이용하여 access token, refresh token을 생성하고 해당 token들을 쿠키에 담아 Serivce Client로 redirect한다.
14. Service Client가 사용자 정보가 필요한 경우, Service Server에게 해당 정보를 요청한다.
15. Service Server가 쿠키에 담긴 access token을 디코딩하여 access token에 담긴 사용한 사용자 정보를 Service Client에게 전달한다.
❓access token과 refresh token을 어디에 담아서 전달할 것인가?
구현 중 가장 많이 고민했던 부분 중 하나였던 것 같다.🫠
1. Query String
URL 주소에 파라미터를 통해 데이터를 전달하는 방식
- 가장 간단한 방법
- URL 주소에 토큰 정보가 다 드러나기 때문에 보안 측면에서 가장 취약하다고 판단
2. Body
Body에 JSON 형식의 데이터를 전달하는 방식
- Spring Security를 사용하지 않고 OAuth2.0을 구현할 때 채택했었음
- Spring Security 사용 시 href를 통한 요청에 대한 response를 받는데 어려움이 있었음
3. Authorizaion Header
헤더에 토큰을 저장하여 전달하는 방식
- Cross-Site Scripting(XSS)에 취약
- 클라이언트 측에서 토큰을 관리해야 함
- 프론트 단에서 매 요청마다 Header에 token 값을 넣어줘야함
4. Cookie
Cookie에 토큰을 저장하여 전달하는 방식
- CSRF 공격에 취약
=> CORS 설정 또는 헤더에 있는 Referer 체크하면 어느정도 해결할 수 있다고 판단
=> 결론) access token과 refresh token을 cookie에 담아서 프론트에게 전달함
'개발 일지' 카테고리의 다른 글
[쁘띠 블로그🎀] auto increment vs. UUID (0) | 2024.05.05 |
---|