본문 바로가기

Backend/Spring | SpringBoot

[OAuth2] 회고4

반응형

Q1. Provider에서 parsing이 정상적으로 이루어 지지 않은것 같다.

ResponseDto를 만들어주어 우회해서 parsing시켜주었다.

➡️ accessToken을 정상적으로 가져온다.

 

Q2. Oauth2를 팝업에서 진행하고 완료시 팝업창 닫고 메인창을 reidrect시키려고 한다.

➡️

Contoller에서 Redirect에 이용할 중간 페이지를 호출하게 한다.

...
  @RequestMapping(value = "/oauthRedirect")
  public String oauth2LoginProcess() {
    String returnPage = "web/common/oauthRedirect";
    return returnPage;
  }
...

 

중간 페이지에서 parameter를 이용해 redirect 및 팝업 닫는 분기점을 만들어준다.

parameter가 없으면 oauth인증할 URL로 이동시킨다.

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Redirect Process JSP</title>

    <!-- 필요한 JS 파일 포함 -->
    <script src="<c:url value="/js/jquery/jquery-3.6.0.js"/>"></script>
    <script>
      $(document).ready(function() {
        // 로그인 성공 여부를 확인합니다.
        const urlParams = new URLSearchParams(window.location.search);
        if (urlParams.has('loginSuccess') && urlParams.get('loginSuccess') === 'true') {
          alert('로그인에 성공하였습니다.');
          window.opener.location.href = '/main'; // 부모 창을 리다이렉트합니다.
          window.close(); // 팝업 창을 닫습니다.
        } else {
          alert('로그인이 필요합니다.');
          window.location.href='/oauth2/authorization/kakao';
        }
      });
    </script>
</head>
<body>

</body>
</html>

 

Redirect 처리를 하는 곳에서 Redirect URL에 대한 처리를 해준다.

(나의 경우에는 Handler에서 처리)

	...
    // Redirect Strategy
    if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
      response.setContentType("application/json;charset=UTF-8");
      response.setStatus(HttpServletResponse.SC_OK);

      Map<String, Object> responseData = new HashMap<>();
      String targetUrl =
          determineTargetUrl(authentication) + "?loginSuccess=true"; // 사용자 역할에 따라 URL 결정
      responseData.put("redirectUrl", targetUrl); // 리디렉션할 URL을 JSON 응답에 포함
      new ObjectMapper().writeValue(response.getWriter(), responseData);
    } else {
      handle(request, response, authentication);
    }
    clearAuthenticationAttributes(request);
  }

  private void handle(HttpServletRequest request, HttpServletResponse response,
      Authentication authentication) throws IOException {
    String targetUrl = determineTargetUrl(authentication) + "?loginSuccess=true";
    log.info("Authentication : " + authentication);

    if (response.isCommitted()) {
      log.info("Response has already been committed. Unable to redirect to "
          + targetUrl);
      return;
    }

    redirectStrategy.sendRedirect(request, response, targetUrl);
  }

  private String determineTargetUrl(final Authentication authentication) {

    Map<String, String> roleTargetUrlMap = new HashMap<>();
    roleTargetUrlMap.put("[ROLE_User]", "/main");

    final Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
    for (final GrantedAuthority grantedAuthority : authorities) {
      String authorityName = grantedAuthority.getAuthority();
      // 권한 확인
      if(roleTargetUrlMap.containsKey(authorityName)){
      // redirect URL을 redirect Process 페이지로 이동하는 URL로 지정
        return "/oauthRedirect"; 
      }
    }
    throw new IllegalStateException();
  }

  private void clearAuthenticationAttributes(HttpServletRequest request) {
    HttpSession session = request.getSession(false);
    if (session == null) {
      return;
    }
    session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
  }
  
  ...
반응형

'Backend > Spring | SpringBoot' 카테고리의 다른 글

[Spring Security] Exception Handler  (0) 2024.07.19
[Oauth2] Implicit Grant vs Authorization Code Grant  (0) 2024.06.20
[TIL] 회고 1  (0) 2024.06.17
[OAuth2] 회고3  (0) 2024.06.14
[Oauth2] 회고2  (0) 2024.06.12