간단히 요약하면 내가 어떠한 서비스를 사용자에게 제공한다고 가정하자.
그렇다면 스스로 애플리케이션 서버를 구축 및 로그인 및 회원가입 서비스를 구현하기위해 사용자로부터 개인정보를 받아 저장하고 관리해야 할 것이다.
하지만 OAuth 2.0을 사용한다면 대분의 로그인, 개인정보 관리 책임을 서드파티 애플리케이션 (Google, Facebook, Kakao 등)에게 위임할 수 있다. (단, 사용자가 기존에 서드파티 서비스에 회원가입이 되어있어야 함)
더 추상적으로 생각해보면 하나의 A라는 애플리케이션만 가입한다면 다양한 애플리케이션에서 각각 사용자가 권한을 부여 받을 필요 없이 A 애플리케이션으로 부터 부여 받은 권한을 다양한 애플리케이션에서 행사 할 수 있다.
Oauth2 로그인 시작전에 가장 중요한 것을 꼭 머리에 넣어놓고 시작하자.
숫자 3이 제일 중요하다. 3!!!!!!!!
자 이 숫자 3이 무엇이냐면 바로 밑에 있는 흐름도를 보면서 설명을 하겠다. 어떤 Oauth2 로그인이든 우리는 최종 사용자의 Oauth2 계정 정보(카카오톡이면 카카오톡 이름, 닉네임, 생일 등) 가져오려면 3번의 요청이 필요하다.
그림에서 Application과 KaKao Server 간에 요청이 3번이다.
'인증 코드 요청', '인증 코드로 토큰 요청', '토큰으로 API 호출'.
여기서 인증 코드 요청은 실제 사용자가 카카오톡 로그인을 하면 1회성 인증 코드를 준다. 이 1회성 인증 코드를 통해 다시 카카오 서버에 인증 코드로 토큰을 요청해야한다. 그러면 토큰이 발급되는데 이걸 다시 한번 이용해서 사용자 정보를 얻어와야 한다.
자 요청이 총 몇번인가? 3번이다.
여기서 딜레마에 빠진다. 스프링 시큐리티의 경우 Oauth2 로그인을 스프링 시큐리티 자체에서 지원한다. 그래서 시큐리티의 Oatuh2 로그인을 사용하면 위 과정 중에서 '인증 코드 요청', '인증 코드로 토큰 요청'이 스킵되고 사용자가 로그인 하는 순간 바로 사용자 정보가 응답으로 온다.
시큐리티의 Oauth2 로그인 로직을 자세히 파헤쳐보지 않았지만 3번이 1번으로 줄어드는 편리함을 제공한다. 하지만 내가 만들려고하는 프로젝트에서는 이 생략 과정이 오히려 어려움을 준다.
또한 자바스크립트에서도 이런 SDK나 플러그인이 존재하더라(프론트 분과 얘기를 통해 알게된 부분). 그래서 SDK나 플러그인을 사용하면 시큐리티의 기능처럼 3번의 요청을 생략해버린다.
자 다시 돌아가서 2번째 그림은 JSP나 머스태치를 이용하지않고, React를 쓰는 FE와 협업할 때의 방식이다.
아까 말했다시피 3번의 요청 중에 첫 번째 요청은 FE에서 처리하고 인증 코드를 백엔드로 보내는 방식을 채택해야한다. 만약 토큰을 넘기거나, FE에서 3번의 요청을 마치고 백엔드로 구글 사용자 정보 같은 것을 넘기면 보안 위험에 빠질 수 있다.
먼저 Oauth2 로그인의 흐름도이다. 카카오를 예시로 들었지만 카카오, 구글, 네이버 등 어떤 회사의 서비스를 이용하든 전체적인 플로우가 똑같다(요청 파라미터만 조금씩 다르지만 이거 또한 표준화가 되어 있는 것인지 거의 비슷하다).
플로우가 똑같은 것을 보여주기 위해서 그림은 카카오지만 구글로 설명하겠다.
https://antdev.tistory.com/category/OAuth/Google%20Login%20API
내가 많은 도움을 받았던 블로그다. 지나가던 백엔드 개발자님의 블로그 글인데 구글 말고도 카카오 로그인도 설명해주셨다.
설명이 나보다 훨씬 좋고, 코드도 정말 간결하다. 그냥 그대로 따라하기만 하면 된다.
구글 Oauth2 로그인의 자세한 코드는 해당 블로그를 참조하자.
구글 로그인을 다 하고나면 마지막에 우리 서버의 AccessToken과 RefreshToken을 발급하면 된다. 그러면 이전 글에서 설명 했듯이 JwtFilter들이 로그인 처리를 해줄 것이다.
나의 첫 프로젝트에서 시큐리티를 이용한 JWT, Oauth2 로그인을 사용해보았다. 진짜 고통의 시간이었다...
시큐리티가 뭔지도 모르는 상황에서 이를 커스터마이징하면서 JWT토큰을 쓰고, Oauth2 로그인까지 접목 시키려고 했더니 뇌정지가 한 두번 온게 아니다.
처음엔 시큐리티의 Oauth2 기능을 이용해서 만들어보려 했지만 내 마음대로 커스터마이징 하기가 힘들어서 포기했고, FE와의 연동을 하는 서버를 만드는 것이 처음이라 거기서 다시 또 큰 리팩토링을 했다.
아마 2~3번의 코드 갈아엎음이 있었던 것 같다. 며칠을 고생해서 만든 코드를 지우는 건 정말 마음이 아프다. 하지만 그 아픈 과정을 참고 다시 처음부터 시작하면 해결되는 문제들이 참 많다.
시큐리티 공부를 하면서 부딪혀서 안되는게 없다는 것을 다시 깨달았다. 또한 코드를 지우는 아픔은 언젠가 무뎌지겠지..