root 폴더를 고려하지 않고 파일에 대한 경로를 모두 상대경로로 작성하고 있었다. JavaScript 파일을 script 태그로 여러 곳에 존재하는 파일에 넣었더니 경로에 따라 작동이 불가능한 경우가 발생했다.
fetch API를 이용해 Ajax로 기능을 구현하고있어서 절대경로가 아닌 url로 작성하는 뻘짓(예를 들어 http://index.php ~~~ )을 하다가 CORS Policy 에러를 직면하게 되었다.
겨우 문제를 해결하니 이제는 SESSION을 통한 인증에서 에러가 발생했다.
이 글에서는 JavaScript - Fetch API와 PHP - header()를 이용하여 CORS와 SESSION을 이용한 문제를 해결해보도록 하겠다.
CORS - Cross-Origin Resource SharingOrigin - MDN Web Docs
SOP - MDN Web Docs
CORS - MDN Web Docs
위의 링크을 참고해 해당 개념에 대해 이해하면 읽기 수월하다.
서로 다른 Origin 끼리는 SOP(Same Origin Policy)의 영향으로 서로 리소스를 주고받지 못한다.
보안 때문에 브라우저는 CORS를 제한한다. 하지만, CORS가 필요한 상황이 존재한다. 이때, 내가 사용한 방법은 fetch API를 이용한 것이다.
document.getElementById('info_btn').addEventListener('click', () => {
fetch ('http://localhost/manage_member/modal_member_info.php', {
method: 'GET',
mode: 'cors', // 모드 명시
cache: 'no-cache'
})
.then((res) => res.text())
.then((modal_data) => {
const modal_content = document.getElementsByClassName('modal-content')[0];
modal_content.innerHTML = modal_data;
});
});
mode는 cors가 default값이다. 명시해주기 위해서 작성했다.
이렇게 http request를 보내면 PHP에서는 아무런 조치를 취하지 않는 경우 에러가 발생한다. 에러 메시지는 Access-Control-Allow-Origin 을 설정해 주어야 한다는 것이다.
Access-Control-Allow-OriginAccess-Control-Allow-Origin - MDN Web Docs
Access-Control-Allow-Origin: * Access-Control-Allow-Origin: <origin> Access-Control-Allow-Origin: null
지정한 임의의 origin으로부터의 요청(request)을 허용 한다.
따라서, 응답을 수행하는 서버에서 header에 이것을 설정해주면 된다.
나는 PHP를 사용하므로 header()를 이용하여 설정해주었다.
// CORS 허용
header("Access-Control-Allow-Origin: {$request_origin}");
Access-Control-Allow-CredentialsAccess-Control-Allow-Credentials - MDN Web Docs
CORS 는 해결하게 되었지만, 해당 Origin에는 내가 가지고 있는 Session에 대한 정보가 없었다. 이것을 해결하기 위해서 다음의 방법을 사용했다.
해당 응답 헤더는 request의 자격 증명 모드(credentials)가 include 일 때 요청한 front-end 의 JavaScript 코드에 응답을 노출할지 결정한다.
fetch API 수정credentials모드를 include로 설정해주었다. 이를 통하여 내가 접속한 곳의 session-id를 쿠키를 통하여 전달해 줄 수 있다.
JavaScript 코드
...
fetch ('http://localhost/manage_member/modal_member_info.php', {
method: 'GET',
mode: 'cors',
cache: 'no-cache',
credentials: 'include' // 요청에 쿠키를 포함하여 전송
})
...
Access-Control-Allow-Credentials를 True로 설정PHP 코드
header("Access-Control-Allow-Credentials: true");
이를 통하여 로그인도 에러 없이 유지된다.
Session을 통한 인증에서는 request시에 credential 이 필요하다. 이때, 설정할 origin에 와일드카드*를 넣는 경우 오류가 발생한다.
header('Access-Control-Allow-Origin: *'); // 오류 발생 !!!