ex03 package에 CorsController을 작성한다.
package com.zerock.controller;
import javax.servlet.http.HttpSession;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import lombok.extern.log4j.Log4j;
@RestController
@Log4j
public class CorsController {
@GetMapping(value="/cors", produces= "text/plain;charset=UTF-8")
public String corsTest(HttpSession session) {
log.info("session : " + session.getId());
return "성공";
}
}
세션이 적용되는 과정을 보기 위해서 다음과 같이 코드를 수정한다.
@RestController
@Log4j
public class CorsController {
@CrossOrigin(origins="http://localhost:5500", allowCredentials="true")
@GetMapping(value="/cors", produces= "text/plain;charset=UTF-8")
public String corsTest(HttpSession session) {
log.info("session : " + session.getId());
if (session.getAttribute("test") != null) {
log.info("value : " + session.getAttribute("test"));
}
else {
session.setAttribute("test", "CORS");
log.info("세션에 test 설정");
}
return "성공";
}
}
Same-origin 에서는 요청을 하면 Session이 유지된다.
클라이언트가 서버에 처음 요청을 하는 경우
session.setAttribute("test", "CORS");
로 세션을 설정하고 그 이후에는 session.getId()
을 이용해 SessionId를 불러온다.
$(document).ready(function() {
$("#test").on("click", function() {
$.ajax({
type:'get',
url:'http://localhost:8081/cors',
success: function(result, status, xhr) {
alert(result);
},
error: function(xhr, status, er) {
alert(er);
}
});
});
});
지금 상태에서 요청을 하면 위와 같이 오류가 발생한다.
컨트롤러 쪽에서 크로스 오리진을 설정하면 성공이 뜨긴한다.
같은 포트인 Same-origin에서는 한번 값을 저장하고 다시 꺼내쓰는건 문제가 없다. 라이브 서버인 5500번 포트에서 ajax로 8081번 포트에 요청하는것 cross origin에서는 값이 뜨는건 성공이 뜨는데 세션이나 쿠키는 유지하지 못한다.
세션아이디 값을 같이 보내서 양쪽의 세팅이 맞아 떨어져야 동작이 완료된다.
클라이언트쪽에서 작업하고 서버쪽에서도 작업해서 양쪽의 설정을 맞춰줘야, 세션을 유지할 수 있다.
<html>
<head>
<title>로그인</title>
</head>
<body>
<h1>
</h1>
<button id="test">테스트</button>
</body>
</html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#test").on("click", function() {
$.ajax({
type:'get',
url:'http://localhost:8081/cors',
xhrFields: {
//withCredentials: 'true'
},
success: function(result, status, xhr) {
alert(result);
},
error: function(xhr, status, er) {
alert(er);
}
});
});
});
</script>
xhrFields: {
//withCredentials: 'true'
},
을 추가하면 아래와 같이
블락되었다는 내용이 나온다. Cridential을 보낼때는 정확히 서버측에 명시를 해줘야한다는 뜻이다. 어느 사이트에서 크로스 오리진을 들어오는지 정확한 Same-origin url을 추가 해줘야한다.
@RestController
@Log4j
public class CorsController {
@CrossOrigin(origins="http://localhost:5500")
@GetMapping(value="/cors", produces= "text/plain;charset=UTF-8")
public String corsTest(HttpSession session) {
log.info("session : " + session.getId());
if (session.getAttribute("test") != null) {
log.info("value : " + session.getAttribute("test"));
}
else {
session.setAttribute("test", "CORS");
log.info("세션에 test 설정");
}
return "성공";
}
}
그리고 나서 요청을 넣어보자
다음과 같은 오류가 뜬다.
allowCredential="true"를 추가해서 다음과 같이 코드를 수정한다.
@CrossOrigin(origins="http://localhost:5500", allowCredentials="true")
그럼 이제 성공이 뜨고
세션ID역시 유지되는것을 확인할 수 있다.
중요한 것은 요청하는 쪽의 프론트의 withCredentials: 'true'
부분과 백앤드의 allowCredentials="true"
부분을 둘 다 설정 해줘야 한다.
라이브 서버를 이용해서 프로젝트를 사용할 때는 ajax부분에 모두 withCredential을 설정해야 한다.
<mvc:cors>
<mvc:mapping
path="/**"
allowed-origins="http://localhost:5500"
allow-credentials="true"/>
</mvc:cors>