Oauth2 진행 흐름
문제를 파악하기에 앞서 Oauth2의 진행 흐름에 대해 알아보았습니다.
그림에서의 Resource Owner 사용자를 의미하며 Client는 백엔드 서버를, Authorization Server와 Resource Server는 구글과 같은 3rd-party를 의미합니다.
진행 흐름은 다음과 같습니다.
- 사용자는 백엔드 서버로 소셜로그인을 요청합니다.
- 요청받은 백엔드 서버는 3rd-party에서 부여해준 Client ID와 함께 사용자의 인증과정을 해당 3rd-party의 Authorization 서버에 요청합니다.
- 사용자는 3rd-party에서 인증과정을 진행하고 백엔드 서버는 Authorization 서버에서 받은 엑세스 토큰을 이용하여 3rd-party의 Resource 서버에서 사용자의 정보를 요청하여 받습니다.
- 이후 사용자에게 랜더링 페이지로 이동시킵니다.
문제 발생
구현되었던 기능의 흐름을 살펴보면 사용자가 모든 Oauth2 인증을 마치고 서버는 사용자의 정보를 response body에 담아 특정 URI로 이동시키 하고있었는데 여기서 문제가 발생하게 되었습니다.
제가 원하던 결과는 클라이언트가 request body에 담긴 정보를 이용하여 특정 작업을 수행한 뒤 사용자에게 렌더링 페이지를 보여주는것 이었습니다.
하지만 위의 사진과 같이 지정된 URI로 리디렉트가 되었지만 response body에 포함된 정보가 브라우저에 노출이 되고 해당 정보를 클라이언트에서 사용할 수가 없었습니다.
문제 원인
처음에는 문제의 원인이 Oauth2 인증과정에서 발생한줄 알았습니다.
하지만 문제의 원인을 찾아 보아보니 의외로 간단했습니다.
이번 프로젝트에서 클라이언트는 서버로부터 동적 정보를 받기위해 Rest API를 사용했습니다.
또한 클라이언트는 Ajax를 사용하여 응답받은 동적 데이터를 비동기를 이용하여 처리하였습니다.
하지만 서버에서 response body에 데이터를 담아 사용자에게 직접 Redirect를 시켜주게 되어 클라이언트에서는 해당 데이터에 접근할 수가 없었던 것이었습니다.
문제 해결
이 문제를 해결하기 위해 서버는 사용자의 정보를 response에 담아주는게 아닌 URI의 쿼리 파라미터로 전달해주고 클라이언트는 쿼리 파라미터에 접근하여 해당 정보를 처리한 뒤, 사용자를 랜더링 페이지로 redirect 시켜주는 방식으로 바꾸었습니다.
위와 같이 서버에서는 Oauth2 인증을 성공적으로 마치고난 뒤 특정 작업을 수행할 클래스를 만들어 줍니다.
@Component
public class Oauth2SuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
var oAuth2User = (OAuth2User)authentication.getPrincipal();
String email = String.valueOf(oAuth2User.getAttributes().get("email")); // Oauth2 사용자 정보 접근
// 해당 서비스에 맞는 로직 실행
// ex) OAuth2User의 정보를 이용하여 비동기로 회원가입 자동 진행
// URI 작성
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
queryParams.add("access_token","ansjdnajsndjasdjnasjd");
queryParams.add("refresh_token","qjwdhdnncanslnklq");
String uri = UriComponentsBuilder
.newInstance()
.scheme("http")
.host("localhost")
.port(3000)
.path("/receive")
.queryParams(queryParams)
.build()
.toString();
getRedirectStrategy().sendRedirect(request,response,uri);
}
}
생성된 클래스에서는 특정 정보(이 경우에는 토큰정보)를 쿼리 파라미터로 만들어 사용자를 redirect 시킵니다.
이후 클라이언트는 쿼리 파라미터에 담긴 토큰정보를 로컬스토리지에 저장시킨 뒤, 사용자를 렌더링 페이지로 이동시켜 문제를 해결할 수 있었습니다.
추가 에러 핸들링
서버 배포당시 발생한 또 다른 에러입니다.
만약 사용자가 Oauth2 인증진행 도중 위와 같은 메세지가 발생한다면 구글 APIs(https://console.cloud.google.com/apis)의 승인된 리디렉션 URI주소를 'http://{백엔드 서버 주소}:8080/login/oauth2/code/google'와 같이 변경 시켜주만 됩니다.
(위의 스크린샷처럼 오류가 발생한다면 '오류 세부정보'를 클릭하여 안내된대로 수행하시면 됩니다.)
'Projects > Team project - 스택오버플로우 클론코딩' 카테고리의 다른 글
CORS 문제 해결 (0) | 2023.06.21 |
---|---|
팀 프로젝트 일지 (0) | 2023.06.14 |