CORS를 통한 Ajax 요청을 사용하는 브라우저의 Set-Cookie
Ajax 로그인/사인업 프로세스를 구현하려고 합니다(인증 사이트 새로 고침 없음).상태를 유지하기 위해 쿠키를 사용합니다.지금쯤은 가지고 있을 줄 알았는데 서버에서 쿠키를 가져온 후 브라우저가 쿠키를 설정하지 않습니다.누구 도와줄 사람?요청 및 응답 헤더는 다음과 같습니다.
Request URL:http://api.site.dev/v1/login
Request Method:POST
Status Code:200 OK
요청 헤더
Accept:application/json, text/plain, */*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:57
Content-Type:application/json;charset=UTF-8
Host:api.site.dev
Origin:http://site.dev
Referer:http://site.dev/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.101 Safari/537.11
withCredentials:true
X-Requested-With:XMLHttpRequest
Request Payload
{"email":"calvinfroedge@gmail.com","password":"foobar"}
응답 헤더
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:X-Requested-With, Content-Type, withCredentials
Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin:http://site.dev
Connection:Keep-Alive
Content-Length:19
Content-Type:application/json
Date:Tue, 08 Jan 2013 18:23:14 GMT
Keep-Alive:timeout=5, max=99
Server:Apache/2.2.22 (Unix) DAV/2 PHP/5.4.7 mod_ssl/2.2.22 OpenSSL/0.9.8r
Set-Cookie:site=%2B1THQQ%2BbZkEwTYFvXFVV5fxi00l2K%2B6fvt9SuHACTNsEwUGzDSUckt38ZeDsNbZSsqzHmPMWRLc84eDLZzh8%2Fw%3D%3D; expires=Thu, 10-Jan-2013 18:23:14 GMT; path=/; domain=.site.dev; httponly
X-Powered-By:PHP/5.4.7
서버로부터 반환된 크롬 네트워크 툴의 쿠키도 표시됩니다.
응답 쿠키
Name: site
Value: %2B1THQQ%2BbZkEwTYFvXFVV5fxi00l2K%2B6fvt9SuHACTNsEwUGzDSUckt38ZeDsNbZSsqzHmPMWRLc84eDLZzh8%2Fw%3D%3D
Domain: .site.dev
Path: /
Expires: Session
Size: 196
Http: ✓
AJAX 요청은 "withCredentials" 설정이 true로 설정되어 있어야 합니다(XmlHttpRequest2 및 fetch에서만 사용 가능).
var req = new XMLHttpRequest();
req.open('GET', 'https://api.bobank.com/accounts', true); // force XMLHttpRequest2
req.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
req.setRequestHeader('Accept', 'application/json');
req.withCredentials = true; // pass along cookies
req.onload = function() {
// store token and redirect
let json;
try {
json = JSON.parse(req.responseText);
} catch (error) {
return reject(error);
}
resolve(json);
};
req.onerror = reject;
CORS, API 보안 및 쿠키에 대한 자세한 설명이 필요한 경우 StackOverflow 코멘트에 해당되지 않습니다.이 주제에 대해 쓴 이 기사를 보세요: http://www.redotheweb.com/2015/11/09/api-security.html
비슷한 문제가 있었는데 브라우저 설정이 서드파티 쿠키를 차단하고 있었습니다(Crome > Settings > Advanced Settings > Privacy > Content Settings > Block thirdparty cookie and site data).차단을 해제하면 문제가 해결되었습니다!
AJAX와 PHP를 사용하여 여러 서브도메인에서 하나의 API 도메인으로 쿠키를 전달하고 CORS를 올바르게 처리해야 했습니다.
이것이 과제이자 해결책이었습니다.
1 - api.example.com의 백엔드 PHP.
2 - one.example.com, two.example.com 등 여러 JS 프론트 엔드
3 - 쿠키는 양방향으로 전달되어야 합니다.
4 - 여러 프런트 엔드에서 api.example.com의 PHP 백엔드로의 AJAX 콜
5 - PHP에서는 $_SERVER["를 사용하고 싶지 않습니다.HTTP_ORIGIN"), 항상 신뢰할 수 있는/안전하다고는 할 수 없습니다(HTTP-ORIGIN이 항상 비어 있는 브라우저도 있었습니다).
단일 프런트 엔드 도메인을 사용하는 PHP에서 이를 수행하는 일반적인 방법은 다음과 같은 방법으로 PHP 코드를 시작하는 것입니다.
header('Access-Control-Allow-Origin: https://one.example.com');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');
header('Access-Control-Allow-Credentials: true');
또한 one.example.com 도메인의 JS에서는 다음을 수행합니다.
jQuery.ajax({
url: myURL,
type: "POST",
xhrFields: {withCredentials: true},
dataType: "text",
contentType: "text/xml; charset=\"utf-8\"",
cache: false,
headers: "",
data: myCallJSONStr,
success: function(myResponse) {.....}
단, API 도메인을 호출하기 위해 여러 서브도메인을 사용하고 있기 때문에 이 기능은 사용할 수 없습니다.
이 솔루션은 쿠키를 전달하고 싶기 때문에 작동하지 않습니다.
header('Access-Control-Allow-Origin: *');
JS 사이트의 쿠키 전달 설정과 충돌합니다.
xhrFields: {withCredentials: true}
제가 한 일은 다음과 같습니다.
1 - GET 파라미터를 사용하여 서브도메인을 전달합니다.
2 - (모든) 서브 도메인만 허용되도록 PHP의 메인 도메인을 하드코드합니다.
다음은 제 솔루션의 JS/JQuery AJAX 부분입니다.
function getSubDomain(){
let mySubDomain = "";
let myDomain = window.location.host;
let myArrayParts = myDomain.split(".");
if (myArrayParts.length == 3){
mySubDomain = myArrayParts[0];
}
return mySubDomain;
}
그리고 AJAX 콜:
let mySubDomain = getSubDomain();
if (mySubDomain != ""){
myURL += "?source=" + mySubDomain + "&end"; //use & instead of ? if URL already has GET parameters
}
jQuery.ajax({
url: myURL,
type: "POST",
xhrFields: {withCredentials: true},
dataType: "text",
contentType: "text/xml; charset=\"utf-8\"",
cache: false,
headers: "",
data: myCallJSONStr,
success: function(myResponse) {.....}
마지막으로 PHP 부분은 다음과 같습니다.
<?php
$myDomain = "example.com";
$mySubdomain = "";
if (isset($_GET["source"])) {
$mySubdomain = $_GET["source"].".";
}
$myDomainAllowOrigin = "https://".$mySubdomain.$myDomain;
$myAllowOrigin = "Access-Control-Allow-Origin: ".$myDomainAllowOrigin;
//echo $myAllowOrigin;
header($myAllowOrigin);
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');
header('Access-Control-Allow-Credentials: true');
중요: 모든 서브도메인에 대해 쿠키를 설정하는 것을 잊지 마십시오.이 경우 쿠키의 도메인은 .example.com입니다(메인 도메인 앞에 점이 있습니다).
<?php
//////////////// GLOBALS /////////////////////////////////
$gCookieDomain = ".example.com";
$gCookieValidForDays = 90;
//////////////// COOKIE FUNTIONS /////////////////////////////////
function setAPCookie($myCookieName, $myCookieValue, $myHttponly){
global $gCookieDomain;
global $gCookieValidForDays;
$myExpires = time()+60*60*24*$gCookieValidForDays;
setcookie($myCookieName, $myCookieValue, $myExpires, "/", $gCookieDomain, true, $myHttponly);
return $myExpires;
}
이 솔루션을 사용하면 example.com 상의 서브도메인에서 api.example.com 상의 API를 호출할 수 있습니다.
NB. 호출 서브도메인이 하나밖에 없는 경우에는 PHP 대신 .htaccess를 사용하여 CORS를 설정하는 것이 좋습니다.다음으로 api.example.com만을 호출하는.htaccess(linux/vlinux)의 예를 나타냅니다.
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "https://one.example.com"
Header set Access-Control-Allow-Headers "Origin, Content-Type, X-Auth-Token"
Header set Access-Control-Allow-Credentials "true"
</IfModule>
이 .htaccess를 api.example.com의 루트에 배치합니다.
언급URL : https://stackoverflow.com/questions/14221722/set-cookie-on-browser-with-ajax-request-via-cors
'programing' 카테고리의 다른 글
| Java EE 6 대스프링 3 스택 (0) | 2023.03.06 |
|---|---|
| json 파일을 찾을 수 없는 이유는 무엇입니까? (0) | 2023.03.06 |
| React에서 CORS 문제를 해결하는 방법JS (0) | 2023.03.06 |
| 루프가 있는 굴절기 사용 (0) | 2023.03.06 |
| Spring Boot 환경 변수 읽기 (0) | 2023.03.06 |