programing

도메인 간 Ajax 요청 후 쿠키 보관

fastcode 2023. 8. 28. 22:47
반응형

도메인 간 Ajax 요청 후 쿠키 보관

실행 중인 Javascript 응용 프로그램10.0.0.1도메인 간 Ajax 호출로 사용자 인증을 시도합니다.

요청은 다음과 같습니다.

function test(again){
  $.ajax({
    type: 'GET',
    url: 'http://example.com/userinfo',
    dataType: 'json',
    success: function(userinfo){
      if(again)
        test(false);}});}
test(true);

서버의 첫 번째 응답은 쿠키 설정을 시도합니다.

Access-control-allow-origin:http://10.0.0.1
Set-Cookie:PHPSESSID=uuj599r4k1ohp48f1poobil665; expires=Sat, 28-Jan-2012 17:10:40 GMT; path=/

그러나 두 번째 요청은 이 쿠키를 포함하지 않으며 해당 도메인에 대한 다른 Ajax 요청도 포함하지 않습니다.

다른 도메인의 쿠키를 읽으려고 하는 것이 아니라 다른 도메인의 프로그램이 자신의 쿠키를 설정하고 읽을 수 있기를 바랍니다.

이것이 가능합니까?

저는 크롬과 파이어폭스 9에서 테스트를 했습니다.

서버가 헤더를 설정해야 합니다.

response.Headers.Add("Access-Control-Allow-Credentials", "true");

클라이언트가 다음으로 설정됨:

xhrFields: {
  withCredentials: true
}

당신이 CORS를 지원하는 브라우저를 사용하는 한, AJAX 요청의 쿠키는 작동해야 합니다.하지만 당신은 설정해야 합니다.withCredentials에서XMLHttpRequest사실대로

참조: 자격 증명 포함 특성

저는 JQuery를 사용하지 않지만 특히 설정을 다루는 질문이 있습니다.withCredentialsJQuery를 통해.

교차 도메인 게시물과 함께 자격 증명을 보내시겠습니까?

아니요, 쿠키는 도메인 간에 공유할 수 없습니다.다음을 사용하여 AJAX 호출에 대해 동일한 오리진 정책을 우회할 수 있습니다.Access-Control-*브라우저에서 헤더를 지원한다고 가정하지만 쿠키의 경우에는 방법이 없습니다.

+Darin Dimitrov는 "쿠키는 이 호출의 발신지인 페이지를 호스팅하는 도메인이 아닌 다른 도메인에서 왔기 때문에 브라우저에 의해 저장되지 않습니다."라고 의심합니다.

그러나 JSONP를 사용할 때 쿠키는 원하는 대로 설정되지만 JSONP는 GET 요청에만 해당됩니다.

나의 해결책은 다음 php 파일을 로드하여 쿠키(PHP 세션 ID)를 검색하는 것입니다.<script>:

<? echo $_GET['callback'] . '("' . session_id() . '")'; ?>

또한 모든 교차 도메인 POST 요청에서 세션 ID를 요청 변수로 전달합니다.

저는 AJAX와 PHP를 사용하여 여러 하위 도메인의 쿠키를 단일 API 도메인으로 전달해야 했습니다.

이것이 당면 과제이자 해결책이었습니다.

1 - api.example.com 의 백엔드 PHP.

2 - one.example.com , two.example.com 등의 여러 JS 프런트 엔드

3 - 쿠키는 양방향으로 전달되어야 합니다.

4 - 여러 프런트 엔드에서 api.example.com 의 PHP 백엔드로 AJAX 호출

5 - PHP에서는 $_SERVER["를 사용하는 것을 선호하지 않습니다.HTTP_ORGIIN"), 항상 신뢰할 수 있는/안전한 것은 아니라고 생각합니다(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 솔루션의 일부입니다.

함수 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 대신 CORS를 설정하기 위해 .htaccess를 사용하는 것을 선호합니다.다음은 api.example.com 을 호출하는 one.example.com 전용의 .htaccess(linux/messages)의 예입니다.

<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/8854816/keeping-the-cookie-after-a-cross-domain-ajax-request

반응형