728x90
- 헤더 설정
- 전송 방식이 Ajax 인지의 여부를 위한 헤더 설정
- xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
- CSRF 같은 경우
- AJAX 같은 경우 직접 생성해 주어야 한다.
-
<meta id="_csrf" name="_csrf" th:content="${_csrf.token}"/>
-
<meta id="_csrf_header" name="_csrf_header" th:content="${_csrf.headerName}"/>
- var csrfHeader = $('meta [name="_csrf_header"]'). attr('content')
- var csrfToken = $('meta [name="_csrf"]'). attr('content’)
- xhr.setRequestHeader(csrfHeader, csrfToken);
-
- Login.html
-
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <meta id="_csrf" name="_csrf" th:content="${_csrf.token}"/> <meta id="_csrf_header" name="_csrf_header" th:content="${_csrf.headerName}"/> <head th:replace="layout/header::userHead"></head> <script> function formLogin(e) { var username = $("input[name='username']").val().trim(); var password = $("input[name='password']").val().trim(); var data = {"username" : username, "password" : password}; // var csrfHeader = $('meta[name="_csrf_header"]').attr('content') // var csrfToken = $('meta[name="_csrf"]').attr('content') $.ajax({ type: "post", url: "/api/login", data: JSON.stringify(data), dataType: "json", beforeSend : function(xhr){ xhr.setRequestHeader(csrfHeader, csrfToken); xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); xhr.setRequestHeader("Content-type","application/json"); }, success: function (data) { console.log(data); window.location = '/'; }, error : function(xhr, status, error) { console.log(error); window.location = '/login?error=true&exception=' + xhr.responseText; } }); } </script> <body> <div th:replace="layout/top::header"></div> <div class="container text-center"> <div class="login-form d-flex justify-content-center"> <div class="col-sm-5" style="margin-top: 30px;"> <div class="panel"> <p>아이디와 비밀번호를 입력해주세요</p> </div> <div th:if="${param.error}" class="form-group"> <span th:text="${exception}" class="alert alert-danger">잘못된 아이디나 암호입니다</span> </div> <form th:action="@{/login_proc}" class="form-signin" method="post"> <input type="hidden" th:value="secret" name="secret_key" /> <div class="form-group"> <input type="text" class="form-control" name="username" placeholder="아이디" required="required" autofocus="autofocus"> </div> <div class="form-group"> <input type="password" class="form-control" name="password" placeholder="비밀번호" required="required"> </div> <button type="submit" onclick="formLogin()" id="formbtn" class="btn btn-lg btn-primary btn-block">로그인</button> </form> </div> </div> </div> </body> </html> - csrf 값을 Ajax로 전달한다.
-
- home.html
-
<!DOCTYPE html> <html lang="ko" xmlns:th="http://www.thymeleaf.org"> <meta id="_csrf" name="_csrf" th:content="${_csrf.token}"/> <meta id="_csrf_header" name="_csrf_header" th:content="${_csrf.headerName}"/> <head th:replace="layout/header::userHead"></head> <script> function messages() { var csrfHeader = $('meta[name="_csrf_header"]').attr('content') var csrfToken = $('meta[name="_csrf"]').attr('content') $.ajax({ type: "post", url: "/api/messages", dataType: "json", beforeSend : function(xhr){ xhr.setRequestHeader(csrfHeader, csrfToken); xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); xhr.setRequestHeader("Content-type","application/json"); }, error : function(xhr, status, error) { console.log(error); if(xhr.responseJSON.status == '401'){ window.location = '/api/login?error=true&exception=' + xhr.responseJSON.message; }else if(xhr.responseJSON.status == '403'){ window.location = '/api/denied?error=true&exception=' + xhr.responseJSON.message; } } }); } </script> <body> <div th:replace="layout/top::header"></div> <div class="container"> <div class="row align-items-start"> <nav class="col-md-2 d-none d-md-block bg-light sidebar"> <div class="sidebar-sticky"> <ul class="nav flex-column"> <li class="nav-item"> <div style="padding-top:10px;" class="nav flex-column nav-pills" aria-orientation="vertical"> <a th:href="@{/}" style="margin:5px;" class="nav-link active">대시보드</a> <a th:href="@{/mypage}" style="margin:5px;" class="nav-link text-primary">마이페이지</a> <a href="a" onclick="messages()" style="margin:5px;" class="nav-link text-primary">메시지</a> <a th:href="@{/config}" style="margin:5px;" class="nav-link text-primary">환경설정</a> </div> </li> </ul> </div> </nav> <div style="padding-top:50px;" class="col"> <div class="container text-center"> <h1 class="text-primary">DASHBOARD</h1> <div class="security"></div> <h1>Core Spring Security 에 오신 것을 환영합니다.</h1> </div> </div> </div> </div> <div th:replace="layout/footer::footer"></div> </body> </html>
-
-
@GetMapping(value = {"/login", "/api/login"}) public String login( @RequestParam(value = "error", required = false) boolean error, @RequestParam(value = "exception", required = false) String exception, Model model) { model.addAttribute("error", error); model.addAttribute("exception", exception); return "/user/login/login"; } @GetMapping(value = {"/denied", "/api/denied"}) public String accessDenied(@RequestParam(value = "exception", required = false) String exception, Model model){ Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); Account account = (Account) authentication.getPrincipal(); model.addAttribute("username", account.getUsername()); model.addAttribute("exception", exception); return "user/login/denied"; } - CSRF TOken을 화면을 Meta로 전달해 줄 수 있다.
- AJAX 같은 경우 직접 생성해 주어야 한다.
728x90
'스프링 시큐리티 > 실전프로젝트 - 인증 프로세스 Ajax 인증 구현' 카테고리의 다른 글
| ch06. Ajax Custom DSLs 구현하기 (0) | 2022.01.21 |
|---|---|
| ch05. 인증 및 인가 예외 처리 - AjaxLoginUrlAuthenticationEntryPoint, AjaxAccessDeniedHandler (0) | 2022.01.21 |
| ch04. 인증 핸들러 - AjaxAuthenticationSuccessHandler, AjaxAuthenticationFailureHandler (0) | 2022.01.20 |
| ch03. 인증 처리자 - AjaxAuthenticationProvider (0) | 2022.01.20 |
| ch02. 인증 필터 - AjaxAuthenticationFilter (0) | 2022.01.20 |