왜 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.