왜 jquery의 .ajax () 메소드가 세션 쿠키를 보내지 않습니까?


338

$.ajax()사이트 를 통해 로그인 한 후 $.ajax()해당 사이트에 두 번째 요청 을 보내려고합니다. 그러나 FireBug를 사용하여 전송 된 헤더를 확인하면 요청에 세션 쿠키가 포함되지 않습니다.

내가 뭘 잘못하고 있죠?


2
ajax의 쿠키는 웹 쿠키 뒤에 올 수 있으며 FireBug는 첫 페이지 쿠키를 잡을 수 있습니다.
Chris

1
나는 무슨 뜻인지 알지 못했지만 브라우저 주소 표시 줄에 요청 URL을 붙여 넣고 Firebug를 다시 확인하면 헤더로 쿠키가 서버로 전송 된 것을 볼 수 있습니다. 어떤 솔루션?
user345625

그래서, 아약스도 같은 방식으로 브라우저를 처리 할 생각은하지 않습니다
user345625

사용중인 코드는 무엇입니까?
Dean Harding

브라우저는 여전히 ajax 요청, jquery 또는 다른 방법으로 서버가 설정 한 쿠키를 생성합니다. Ajax 요청에 대한 응답을 확인하고 쿠키가 서버에서 다시 설정되도록 설정 했습니까? 쿠키 등을 설정하지 않는 서버 코드에 문제가있을 수 있습니다.
David

답변:


218

호출하는 URL이 호출 스크립트와 동일한 도메인에있는 경우 AJAX 호출은 쿠키를 보냅니다.

도메인 간 문제 일 수 있습니다.

www.domain-a.com호출 스크립트가 켜져있는 동안 URL을 호출하려고 시도했을 수 있습니다 www.domain-b.com(즉, 크로스 도메인 호출을 한 경우 브라우저는 개인 정보를 보호하기 위해 쿠키를 보내지 않습니다).

이 경우 옵션은 다음과 같습니다.

  • 도메인 b에 상주하고 요청을 도메인 a로 전달하는 작은 프록시를 작성하십시오. 브라우저는 프록시가 호출 스크립트와 동일한 서버에 있기 때문에 프록시를 호출 할 수 있습니다.
    그런 다음이 프록시를 도메인 a로 보낼 수있는 쿠키 이름 및 값 매개 변수를 승인하도록 구성 할 수 있습니다. 그러나 이것이 작동하려면 쿠키의 이름과 도메인의 서버 가치를 알아야합니다. 인증을 원합니다.
  • JSON 객체를 가져 오는 경우 대신 JSONP 요청을 사용하십시오. jQuery는이를 지원합니다. 그러나 유효한 JSONP 응답을 반환하도록 도메인 a에서 서비스를 변경해야합니다.

그것이 조금이라도 도움이된다면 기쁘다.


19
쿠키를 특정 경로로 설정할 수 있으므로 쿠키가 설정되어 path=/something있고 페이지 /another를 요청하는 경우 쿠키가 전송되지 않습니다. 페이지를 요청하면 /something쿠키가 예상대로 전송됩니다. 쿠키를 설정하는 코드도 확인하십시오.
styfle

2
jsonp 요청이 coockies를 보내나요?
albanx

1
@albanx 예, 요구 사항이 설정되어 있다면 가능합니다. 그것은 다른 것과 마찬가지로 정상적인 요청이며 쿠키를 보냅니다.
flu

1
@albanx이 다른 관련 질문 에는 사용자 정의 쿠키로 JSONP 요청을 수행하는 방법에 대한 예가 포함되어 있습니다.
AntonioHerraizS

4
에 따르면 JSONP 위키 백과>이 방법은 CORS에 찬성 버려진
피터 Dotchev

388

도메인 간 시나리오에서 작업하고 있습니다. 로그인하는 동안 원격 서버는 Set-Cookie 헤더 Access-Control-Allow-Credentials를 true 로 설정하여 반환 합니다.

원격 서버에 대한 다음 ajax 호출은이 쿠키를 사용해야합니다.

CORS Access-Control-Allow-Credentials는 도메인 간 로깅을 허용합니다. 예는 https://developer.mozilla.org/En/HTTP_access_control 을 확인 하십시오 .

나에게 그것은 JQuery의 버그 (또는 적어도 다음 버전의 기능) 인 것 같습니다.

최신 정보:

  1. 쿠키가 AJAX 응답에서 자동으로 설정되지 않습니다 (인용 : http://aleembawany.com/2006/11/14/anatomy-of-a-well-designed-ajax-login-experience/ )

    왜?

  2. 응답에서 쿠키 값을 가져와 수동으로 설정할 수는 없습니다 ( http://www.w3.org/TR/XMLHttpRequest/#dom-xmlhttprequest-getresponseheader )

    혼란 스러워요 ..

    매개 변수 jquery.ajax()설정 을 요청하는 방법이 있어야합니다 XMLHttpRequest.withCredentials = "true".

답변 : http://api.jquery.com/jQuery.ajax/의xhrFields 매개 변수를 사용해야합니다

설명서의 예는 다음과 같습니다.

$.ajax({
   url: a_cross_domain_url,
   xhrFields: {
      withCredentials: true
   }
});

서버가이 요청에 올바르게 응답하는 것도 중요합니다. @ Frédéric 및 @Pebbl의 훌륭한 의견을 여기에 복사하십시오.

Important note: when responding to a credentialed request, server must specify a domain, and cannot use wild carding. The above example would fail if the header was wildcarded as: Access-Control-Allow-Origin: *

따라서 요청이 다음과 같은 경우

Origin: http://foo.example
Cookie: pageAccess=2

서버는 다음과 같이 응답해야합니다.

Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Credentials: true

[payload]

그렇지 않으면 페이로드가 스크립트로 반환되지 않습니다. 참조 : https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials


8
대단해! 나는 이것을 사용하기 위해 추가 + 서버 측에서 Access-Control-Allow-Credentials 헤더를 true로 설정
Frédéric

그리고 헤더 본문에서 요청 자격 증명에서 이러한 자격 증명을 어디에 설정합니까?
Francisco Corrales Morales

3
답변 주셔서 감사합니다 :) 빠른 추가, Important note: when responding to a credentialed request, server must specify a domain, and cannot use wild carding. The above example would fail if the header was wildcarded as: Access-Control-Allow-Origin: * developer.mozilla.org/en-US/docs/Web/HTTP/…를
Pebbl

불행히도 이것 중 어느 것도 나를 위해 일하지 않았습니다. AngularJS에서 동일한 요청을 실행하면 작동하지만 jQuery에서는 이러한 제안으로도 세션 쿠키가 전달되지 않습니다. (jQuery v2.1.1)
지리학 적

(OO) 당신은 여러 가지 고통스러운 시간에서 나를 구해 주셨습니다. 완벽한 답변입니다! 감사! <IfModule mod_headers.c> 헤더 세트 Access-Control-Allow-Origin " localhost "헤더 세트 Access-Control-Allow-Credentials "true"</ IfModule>
Vinay Vissh

48

사용

xhrFields: { withCredentials:true }

내 jQuery ajax 호출의 일부로 솔루션의 일부였습니다. 또한 리소스에서 OPTIONS 응답으로 헤더를 반환해야했습니다.

Access-Control-Allow-Origin : http://www.wombling.com
Access-Control-Allow-Credentials : true

단지 것이 중요 하나 "출처"를 허용하는 옵션이 호출의 응답 헤더에 있었고, 하지 "*". 요청의 출처를 읽고 응답에 다시 입력하여이를 달성했습니다. 아마도 제한의 원래 이유를 피할 수는 있지만 사용 사례에서는 보안이 가장 중요하지 않습니다.

W3C 표준은 공백으로 구분 된 목록을 허용하기 때문에 하나의 원점에 대한 요구 사항을 명시 적으로 언급 할 가치가 있다고 생각했지만 Chrome은 그렇지 않습니다! http://www.w3.org/TR/cors/#access-control-allow-origin-response-header NB "실제"비트.


41

이것을 init 함수에 넣으십시오.

$.ajaxSetup({
  xhrFields: {
    withCredentials: true
  }
});

작동합니다.


1
당신은 내 하루를 구했다! 자격 증명이있는 메소드 수준에서는 저에게 효과적이지 않았습니다. 그러나 이와 같은 세계화는 마침내 작동합니다! 감사.
Paulius Matulionis

가 (이 예상되지 않는 및 액세스 제어 - 허용 - 자격 증명이 필요하여 요청 실패) 다른 도메인 에테르, 모든 요청에 쿠키를 전송하기 때문에, 그것으로주의
gdbdable

12

이미이 질문에 대한 좋은 답변이 많이 있지만 쿠키 도메인이 일치하기 때문에 세션 쿠키가 전송 될 것으로 예상되는 경우를 명확히하는 것이 도움이 될 수 있다고 생각했지만 AJAX 요청이 있기 때문에 전송되지 않습니다. 다른 하위 도메인으로 만들어지고 있습니다. 이 경우 * .mydomain.com 도메인에 할당 된 쿠키가 있으며 different.mydomain.com " 에 대한 AJAX 요청에 포함 시키려고 합니다 . 기본적으로 쿠키는 전송되지 않습니다. 이 문제를 해결하기 위해 세션 쿠키에서 HTTPONLY를 비활성화 할 필요는 없으며, 제안 된 작업 ( https://stackoverflow.com/a/23660618/545223 ) 만 수행하고 다음을 수행하면됩니다.

1) 아약스 요청에 다음을 추가하십시오.

xhrFields: { withCredentials:true }

2) 다른 하위 도메인의 리소스에 대한 응답 헤더에 다음을 추가하십시오.

Access-Control-Allow-Origin : http://original.mydomain.com
Access-Control-Allow-Credentials : true

7

다른 솔루션을 시도했지만 여전히 작동하지 않는 경우 문제가 무엇인지 알아 냈습니다. contentType을 "application / json"에서 "text / plain"으로 변경했습니다.

$.ajax(fullUrl, {
    type: "GET",
    contentType: "text/plain",
    xhrFields: {
         withCredentials: true
    },
    crossDomain: true
});

4

나는이 같은 문제가 있었고 스크립트가 단순히 sessionid 쿠키를 얻지 못하고 있는지 확인했습니다.

내 프레임 워크 (Django)가 기본적으로 HttpOnly를 사용하여 sessionid 쿠키를 전달하고 있음을 브라우저에서 sessionid 쿠키 값을 확인하여 알아 냈습니다. 이는 스크립트가 sessionid 값에 액세스 할 수 없으므로 요청과 함께 전달하지 않았 음을 의미합니다. 많은 것들이 액세스 제한이 필요한 Ajax를 사용할 때 HttpOnly가 기본값이 될 것이라는 것은 우스운 일입니다.

이 문제를 해결하기 위해 설정 (SESSION_COOKIE_HTTPONLY = False)을 변경했지만 다른 경우 쿠키 경로에서 "HttpOnly"플래그 일 수 있습니다.


2
이러지 마십시오. 클라이언트 측 스크립트는 가장 일반적인 XSS 공격 경로 인 세션 쿠키에 액세스 할 수 있습니다. owasp.org/index.php/HttpOnly
Jason Elkin

1

위의 답변에 설명 된 단계 외에도 localhost로컬 호스트 에서 또는 포트와 같은 포트를 개발하는 localhost:8080경우 Set-Cookie 헤더의 도메인 값을 전달하지 않아야합니다. Set-Cookie 헤더에서
도메인을 설정할 수 없습니다. localhost올바르지 않습니다. 도메인을 생략하면됩니다.

명시 적 도메인이 있는 localhost의 쿠키asp.net이 localhost에서 쿠키를 생성하지 않는 이유를 참조하십시오 .


0

localhost 및 dev 환경에서 PHPSESSID 쿠키 문제를 설정하는 데 2 ​​센트. locahost의 REST API 엔드 포인트에 대한 AJAX 호출을 작성합니다. 주소가 mysite.localhost/api/member/login/(내 개발 환경의 가상 호스트) 라고 말하십시오 .

  • Postman 에서이 요청을 수행하면 문제가 없으며 PHPSESSID가 응답으로 설정됩니다.

  • Browsersync 프록시 페이지 (예 : 122.133.1.110:3000/test/api/login.php브라우저 주소 표시 줄)에서 AJAX를 통해이 엔드 포인트를 요청하면 mysite.localhost쿠키간에 PHPSESSID가 나타나지 않습니다.

  • 동일한 도메인의 페이지에서 직접 요청하면 (예 : mysite.localhost/test/api/login.phpPHPSESSID) 제대로 설정됩니다.

따라서 이것은 위의 @flu answer에 언급 된 출처 간 요청 쿠키 문제입니다.


0

다른 사람을 도울 수 있도록 시나리오와 솔루션을 추가하십시오. RESTful API를 사용할 때 비슷한 경우가 발생했습니다. HTML / Script / CSS 파일을 호스팅하는 웹 서버와 API를 노출하는 Application Server가 동일한 도메인에서 호스팅되었습니다. 그러나 경로는 달랐습니다.

웹 서버 -mydomain / webpages /abc.html

mycookie 라는 쿠키를 설정 하는 abc.js 를 사용 했습니다.

앱 서버 -mydomain / webapis / servicename

API 호출을 한 사람

mydomain / webapis / servicename의 쿠키를 예상하고 그것을 읽으려고했지만 전송되지 않았습니다. 답변에서 의견을 읽은 후 브라우저 개발 도구에서 mycookie의 경로가 "/ webpages " 로 설정 되어 서비스 호출에서 사용할 수 없음을 확인했습니다.

mydomain / webapis / servicename

jquery에서 쿠키를 설정하는 동안 이것이 내가 한 일입니다.

$.cookie("mycookie","mayvalue",{**path:'/'**});

-5

아마도 100 % 질문에 대답하지는 않았지만 innovastudio 편집기의 자산 관리자에서 파일 업로드를 아약스 게시 할 때 세션 문제를 해결하기 위해이 스레드를 우연히 발견했습니다. 결국 솔루션은 간단했습니다. 플래시 업 로더가 있습니다. 비활성화 (설정

var flashUpload = false;   

in asset.php)와 표시등이 다시 깜박이기 시작했습니다.

이러한 문제를 디버깅하기가 매우 어려울 수 있으므로 업로드 핸들러에 다음과 같은 것을 넣으면 올바른 트랙에 당신을 설정할 수 있습니다.

$sn=session_name();
error_log("session_name: $sn ");

if(isset($_GET[$sn])) error_log("session as GET param");
if(isset($_POST[$sn])) error_log("session as POST param");
if(isset($_COOKIE[$sn])) error_log("session as Cookie");
if(isset($PHPSESSID)) error_log("session as Global");

로그에 뛰어 들었고 쿠키가 전송되지 않은 누락 된 세션을 빠르게 발견했습니다.


세션 쿠키가 없을 때 $ sn의 값은 무엇입니까? (임의의 하나, 또는 어쩌면 널 (null)), 또는 사용자가 예를 들어 GET 값에서 session_name을 설정할 수 있습니다 session_name(isset($_GET['sess']) ? $_GET['sess'] : null);session_start();이런 식으로, 그들은 작동하는 것을 얻을 것
스틸 뇌

이것이 내가 문제를 발견 한 방법입니다.이 플래시 업 로더에서 게시 할 때 세션이 없습니다. GET 변수 세션 식별자를 사용하는 것은 나쁜 생각이며 쿠키가 작동하지 않아서 버렸습니다. 어쨌든 플래시는 과거의 일입니다.
Ellert van Koperen
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.