[Tistory] [Project] google Oauth2 로그인 시 refreshToken을 받는 방법 (최초 로그인에서 저장을 못했을 때)

원글 페이지 : 바로가기

서론 tincle이라는 프로젝트를 진행 중에 일어난 일입니다. 1차 MVP에서는 google과 kakao의 회원가입 기능만 개발하기로 해서 회원가입 기능만 개발했었습니다. 1차를 완료한 후 2차 개발이 시작되었는데, 2차에서 플레이스토어 배포를 위해 회원 탈퇴기능을 구현해야 했습니다. 그 과정에서 최초 google 로그인에서 refreshToken을 저장하지 못했을 때 다시 발급 받는 과정에 어려움이 있어 다른 누군가에게 도움이 되기 위해 이 글을 적습니다. google 로그인과 회원 탈퇴 로직 보기(Java/Spring) -> https://github.com/DoDream-dev/Tinqle-Server/blob/develop/src/main/java/tinqle/tinqleServer/domain/account/service/GoogleService.java 처음에는 최초 로그인 시에 google accessToken으로 refreshToken을 발급받고 DB에 저장해놓았다가 회원 탈퇴 시에 DB에 저장된 refreshToken을 활용해서 google accessToken을 발급받아 회원 탈퇴하는 로직을 구현했습니다. 모든게 순조롭게 이뤄지는 도중 에러가 나와서 디버그를 해본 결과… refreshToken이 null 값으로 오고있었다… !!!! 왜 null 값으로 오는지 검색해 본 결과 google refreshToken은 최초 로그인 시에 발급하고, 재 로그인시에는 refreshToken을 주지 않습니다. 즉 최초 로그인 시에 refreshToken을 저장하지 않으면 다시 발급받아야 하는 상황입니다. 저는 최초 가입시 refreshToken을 저장하는 로직을 만들어 놓지 않았고, 그 refreshToken을 다시 얻을 수 없었습니다. 이를 해결하기 위해 여러 방법을 시도해봤습니다. 출처: https://velog.io/@semi-cloud/Oauth-%EA%B5%AC%EA%B8%80%ED%95%9C%ED%85%8C-%EC%A7%80%EC%86%8D%EC%A0%81%EC%9C%BC%EB%A1%9C-%EB%A6%AC%ED%94%84%EB%A0%88%EC%8B%9C-%ED%86%A0%ED%81%B0%EC%9D%84-%EB%B0%9B%EC%95%84%EB%82%B4%EB%8A%94-%EB%B0%A9%EB%B2%95 시도 1 : 사용자가 앱과의 연결을 삭제하면 refreshToken을 다시 주지 않을까? 생각해서 다음과 같이 연결을 삭제해보았습니다. 그 결과는.. 실패.. 여전히 null 값으로 오고 있었습니다. 시도 2 : 로그인 시 코드를 요청할 때 파라미터에 prompt = consent를 추가하면 매번 동의를 얻고 refreshToken을 준다고 하여 이 파라미터를 추가 후에 다시 디버그를 해보았습니다. 그 결과.. 아쉽게도 실패..했습니다. 시도 3 : 출처 : https://hyeonic.github.io/woowacourse/dallog/google-refresh-token.html#refresh-token%E1%84%8B%E1%85%A6-%E1%84%8E%E1%85%A2%E1%84%8B%E1%85%AF%E1%84%8C%E1%85%B5%E1%86%AB-null 정리하면 Google OAuth 2.0 서버로 리디렉션 (opens new window)할 때 query parameter에 access_type을 offline으로 설정해야 한다는 것이다. 다시 되돌아 가서 Google 인증 요청을 위한 uri를 생성하는 메서드를 아래와 같이 수정하였다. 이와 같이 설정하였더니…!!!! 드디어 성공했다..!!!!! 역시 구글 문서는 자세히 읽어봐야 하는 것 같다.. 결과 : https://accounts.google.com/o/oauth2/v2/auth ?client_id={client_id} &redirect_uri={리다이렉션 url} &scope=https://www.googleapis.com/auth/userinfo.profile &response_type=code&prompt=consent&access_type=offline 위와 같이 끝에 파라미터에 prompt=consent&access_type=offline 추가했더니 refreshToken이 정상적으로 나왔다! 문제점 하지만 여기서 문제가 하나 있다. 단순히 prompt를 consent로 설정할 경우 우리 서비스에 가입된 사용자는 Google OAuth 2.0 인증을 진행할 때 매번 재로그인을 진행해야 한다. 이것은 사용자에게 매우 불쾌한 경험으로 다가올 수 있다. 아직 초반이라 테스터 회원들밖에 없어서 다행이지만, 배포할 때는 처음에 가입할 때 refreshToken을 저장하는 로직을 추가해서 prompt를 제거하도록 하자. (최초 발급에는 refreshToken을 잘 준다.. 이걸 잘 저장하자.) 개발할 때 refreshToken이 필요하다면 개발 환경과 운영 환경을 분리하는 방법 있다! 운영 환경: Refresh Token 발급을 위해 accept_type을 offline으로 설정한다. 단 최초 로그인에만 Refresh Token을 발급 받기 위해 prompt는 명시하지 않는다. 개발 환경: 개발 환경에서는 매번 DataBase가 초기화 되기 때문에 Refresh Token을 유지하여 관리할 수 없다. 테스트를 위한 추가적인 Google Cloud Project를 생성한 뒤, accept_type을 offline으로, prompt는 consent로 설정하여 매번 새롭게 Refresh Token을 받도록 세팅한다. 만약 필요하다면 분리하자. google 로그인과 회원 탈퇴 로직 보기(Java/Spring) -> https://github.com/DoDream-dev/Tinqle-Server/blob/develop/src/main/java/tinqle/tinqleServer/domain/account/service/GoogleService.java 참고: https://hyeonic.github.io/woowacourse/dallog/google-refresh-token.html#%E1%84%8B%E1%85%A5%E1%86%B7%E1%84%80%E1%85%A7%E1%86%A8%E1%84%92%E1%85%A1%E1%86%AB-google https://doogle.link/%EA%B5%AC%EA%B8%80-%EC%95%84%EC%9D%B4%EB%94%94%EB%A1%9C-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EA%B5%AC%ED%98%84%EC%A4%91-%EB%A6%AC%ED%94%84%EB%A0%88%EC%8B%9C-%ED%86%A0%ED%81%B0refresh-token-%EC%9D%B4/ https://velog.io/@semi-cloud/Oauth-%EA%B5%AC%EA%B8%80%ED%95%9C%ED%85%8C-%EC%A7%80%EC%86%8D%EC%A0%81%EC%9C%BC%EB%A1%9C-%EB%A6%AC%ED%94%84%EB%A0%88%EC%8B%9C-%ED%86%A0%ED%81%B0%EC%9D%84-%EB%B0%9B%EC%95%84%EB%82%B4%EB%8A%94-%EB%B0%A9%EB%B2%95

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다