Cookies trên localhost với tên miền rõ ràng


191

Tôi phải thiếu một số điều cơ bản về cookie. Trên localhost, khi tôi đặt cookie ở phía máy chủ chỉ định tên miền rõ ràng là localhost (hoặc .localhost). cookie dường như không được chấp nhận bởi một số trình duyệt.

Firefox 3.5: Tôi đã kiểm tra yêu cầu HTTP trong Fireorms. Những gì tôi thấy là:

Set-Cookie:
    name=value;
    domain=localhost;
    expires=Thu, 16-Jul-2009 21:25:05 GMT;
    path=/

hoặc (khi tôi đặt tên miền thành .localhost):

Set-Cookie:
    name=value;
    domain=.localhost;
    expires=Thu, 16-Jul-2009 21:25:05 GMT;
    path=/

Trong cả hai trường hợp, cookie không được lưu trữ.

IE8: Tôi không sử dụng bất kỳ công cụ bổ sung nào, nhưng cookie dường như cũng không được lưu trữ, vì nó không được gửi lại trong các yêu cầu tiếp theo.

Opera 9.64: Cả localhost và .localhost đều hoạt động , nhưng khi tôi kiểm tra danh sách cookie trong Tùy chọn, tên miền được đặt thành localhost.local mặc dù được liệt kê trong localhost (trong nhóm danh sách).

Safari 4: Cả localhost và .localhost đều hoạt động , nhưng chúng luôn được liệt kê là .localhost trong Tùy chọn. Mặt khác, một cookie không có tên miền rõ ràng, nó được hiển thị dưới dạng localhost (không có dấu chấm).

Vấn đề với localhost là gì? Do số lượng không nhất quán như vậy, phải có một số quy tắc đặc biệt liên quan đến localhost. Ngoài ra, nó không hoàn toàn rõ ràng với tôi tại sao các tên miền phải được thêm tiền tố bởi một dấu chấm? RFC 2109 tuyên bố rõ ràng rằng:

Giá trị cho thuộc tính Miền không chứa dấu chấm nhúng hoặc không bắt đầu bằng dấu chấm.

Tại sao? Tài liệu chỉ ra rằng nó phải làm một cái gì đó với bảo mật. Tôi phải thừa nhận rằng tôi chưa đọc toàn bộ thông số kỹ thuật (có thể thực hiện sau), nhưng nghe có vẻ hơi lạ. Dựa trên điều này, việc thiết lập cookie trên localhost sẽ là không thể.


13
Chủ đề 6 tuổi và đây vẫn là một vấn đề. Tôi đang sử dụng Chrome v40. Xem ở đây .
Gaui

5
Chrome 43 ... vẫn là một lỗi.
Evan Carroll

4
Chrome 54 ở đây, KHÔNG được giải quyết
Vahid Amiri

6
Chrome 73 .. vẫn phải đối mặt với cùng một vấn đề. :(
Code_Crash

2
Bất cứ ai cũng có thể giải quyết điều này? Vẫn đối mặt với cùng một *** .. xem câu trả lời SO này
Bonjour123

Câu trả lời:


235

Theo thiết kế, tên miền phải có ít nhất hai dấu chấm; nếu không trình duyệt sẽ coi chúng không hợp lệ. (Xem tài liệu tham khảo trên http://curl.haxx.se/rfc/cookie_spec.html )

Khi làm việc trên localhost, tên miền cookie phải được bỏ qua hoàn toàn. Chỉ đặt nó thành ""hoặc NULLhoặc FALSEthay vì "localhost"là không đủ.

Đối với PHP, hãy xem nhận xét trên http://php.net/manual/en/feft.setcookie.php#73107 .

Nếu làm việc với API Java Servlet, đừng gọi cookie.setDomain("...")phương thức nào cả.


93
Không chắc chắn lý do tại sao mọi người đều +1, tôi đặt tên miền của cookie thành null hoặc chuỗi sai hoặc chuỗi trống và nó vẫn không lưu nếu trên localhost.
Justin

5
Tôi không thấy bất cứ nơi nào trong RFC6265 về hai dấu chấm trong miền: tools.ietf.org/html/rfc6265#section-5.2.3 .Net nói đặt nó thành ".local" cho tất cả các máy chủ trong miền địa phương của bạn. Điều này có vẻ phù hợp với Opera / Safari msdn.microsoft.com/en-us/l
Library / rach3yd2.aspx

9
@Justin: Hừm, có lẽ bạn cần bỏ hoàn toàn Domain=tham số khi đặt cookie. Nếu bạn chỉ đặt tên miền thành null hoặc trống, có thể khung của bạn sẽ gửi Domain=tham số với giá trị đó, thay vì bỏ qua nó? Kiểm tra với ví dụ Firebird.
sleske

2
@Ralph, một triệu lời cảm ơn, điều này đã khiến tôi phát điên trong vài giờ. Hy vọng rằng việc đặt Miền thành null (Tôi đang ở trong ngăn xếp máy chủ .Net) hoạt động như một cơ duyên.
Xose Lluis

4
Điều này có phần kém từ. "Đặt thành null hoặc chuỗi sai hoặc chuỗi rỗng" nên đọc "Không đặt phần 'tên miền' của cookie." Ví dụ: sử dụng một thử nghiệm đơn giản để loại bỏ hoàn toàn phần tên miền của cookie hoạt động cho localhost:((domain && domain !== "localhost") ? ";domain="+domain : "")
L0j1k

33

Tôi đồng ý rộng rãi với @Ralph Buchfelder, nhưng đây là một số khuếch đại của điều này, bằng thử nghiệm khi cố gắng sao chép một hệ thống với một số tên miền phụ (như example.com, fr.example.com, de.example.com) trên máy cục bộ của tôi ( Hệ điều hành X / Apache / Chrome | Firefox).

Tôi đã chỉnh sửa / etc / hosts để chỉ một số tên miền phụ tưởng tượng ở 127.0.0.1:

127.0.0.1 localexample.com
127.0.0.1 fr.localexample.com
127.0.0.1 de.localexample.com

Nếu tôi đang làm việc trên fr.localexample.com và tôi bỏ tham số tên miền, cookie sẽ được lưu trữ chính xác cho fr.localexample.com, nhưng không hiển thị trong các tên miền phụ khác.

Nếu tôi sử dụng tên miền của ".localexample.com", các cookie được lưu trữ một cách chính xác cho fr.localexample.com, và được nhìn thấy trong các tên miền phụ khác.

Nếu tôi sử dụng tên miền "localexample.com" hoặc khi tôi đang thử một tên miền chỉ "localexample" hoặc "localhost", cookie sẽ không được lưu trữ.

Nếu tôi sử dụng tên miền "fr.localexample.com" hoặc ".fr.localexample.com", cookie sẽ được lưu trữ chính xác cho fr.localexample.com và vô hình (chính xác) trong các tên miền phụ khác.

Vì vậy, yêu cầu bạn cần ít nhất hai dấu chấm trong miền có vẻ là chính xác, mặc dù tôi không thể hiểu tại sao nên như vậy.

Nếu bất cứ ai muốn thử điều này, đây là một số mã hữu ích:

<html>
<head>
<title>
Testing cookies
</title>
</head>
<body>
<?php
header('HTTP/1.0 200');
$domain = 'fr.localexample.com';    // Change this to the domain you want to test.
if (!empty($_GET['v'])) {
    $val = $_GET['v'];
    print "Setting cookie to $val<br/>";
    setcookie("mycookie", $val, time() + 48 * 3600, '/', $domain);
}
print "<pre>";
print "Cookie:<br/>";
var_dump($_COOKIE);
print "Server:<br/>";
var_dump($_SERVER);
print "</pre>";
?>
</body>
</html>

30

localhost: Bạn có thể sử dụng: domain: ".app.localhost"và nó sẽ hoạt động. Các tham số 'miền' cần 1 hoặc nhiều dấu chấm trong tên miền để thiết lập các tập tin cookie. Sau đó, bạn có thể có các phiên làm việc trên các tên miền phụ localhost như : api.app.localhost:3000.


1
Cũng đã thử nghiệm và làm việc trên máy chủ node.js, sử dụng Express 3.x, trongexpress.session({cookie: { domain: '.app.localhost', maxAge: 24 * 60 * 60 * 1000 }})
AmpT

3
Nên chọn câu trả lời này nếu bạn đang sử dụng tên miền địa phương! Đặt một dấu chấm trước khi tên miền phụ khắc phục vấn đề của tôi.
Foxhoundn

1
Vì vậy, việc chuẩn bị này .app.đến từ đâu? Đây có phải là một phần của một số đặc biệt không? Và nó có áp dụng cho tất cả các miền không phù hợp (những miền không có hai dấu chấm) không? Ngoài ra, điều này sẽ làm việc với các trình duyệt cũ? : ^)
user2173353

Ồ ... giờ thì tôi đã hiểu ... Nó chỉ là một mẹo để đánh lừa các trình duyệt. ĐỒNG Ý.
dùng2173353

14

Khi cookie được đặt với tên miền rõ ràng là 'localhost' như sau ...

Đặt-Cookie: tên = giá trị; tên miền = localhost ; hết hạn = Thu, 16-tháng 7 năm 2009 21:25:05 GMT; đường dẫn = /

... Sau đó, các trình duyệt bỏ qua nó vì nó không bao gồm ít nhất hai giai đoạn và không phải là một trong bảy tên miền cấp cao nhất được xử lý đặc biệt .

... các tên miền phải có ít nhất hai (2) hoặc ba (3) khoảng thời gian để ngăn chặn các tên miền có dạng: ".com", ".edu" và "va.us". Bất kỳ tên miền nào không thành công trong một trong bảy tên miền cấp cao đặc biệt được liệt kê bên dưới chỉ yêu cầu hai giai đoạn. Bất kỳ tên miền khác yêu cầu ít nhất ba. Bảy tên miền cấp cao đặc biệt là: "COM", "EDU", "NET", "ORG", "GOV", "MIL" và "INT".

Lưu ý rằng số lượng thời gian trên có thể giả định rằng một giai đoạn hàng đầu là bắt buộc. Tuy nhiên, khoảng thời gian này bị bỏ qua trong các trình duyệt hiện đại và có lẽ nên đọc ...

ít nhất một (1) hoặc hai (2) tiết

Lưu ý rằng giá trị mặc định cho thuộc tính miền là tên máy chủ của máy chủ đã tạo phản hồi cookie .

Vì vậy, một cách giải quyết cho các cookie không được đặt cho localhost chỉ đơn giản là không chỉ định thuộc tính miền và để trình duyệt sử dụng giá trị mặc định - điều này dường như không có các ràng buộc giống như giá trị rõ ràng trong thuộc tính miền.


Tôi đã không DV, nhưng tôi đoán lý do mà người khác làm là vì câu trả lời của bạn không thực sự bổ sung nhiều giá trị. Cả hai giai đoạn yêu cầu và để trống thuộc tính miền đã được thảo luận trong các câu trả lời khác. Ngoài ra, những thứ bạn đã thêm về một tên miền cấp cao nhất dường như không chính xác. Theo kinh nghiệm của tôi đó không phải là một yêu cầu.
TTT

@TTT Không chắc chắn nếu bạn nhận được bit trong câu trả lời của tôi, nơi tôi nói rằng nó nên có ít nhất 1 hoặc hai giai đoạn tùy thuộc vào TLD vì các giai đoạn hàng đầu bị bỏ qua? Vì vậy, tôi đã cung cấp một số thông tin cơ bản về vấn đề này và thêm một điểm mà tôi không nghĩ là được đề cập ở nơi khác - các quy tắc khác nhau đối với một miền rõ ràng và một quy tắc mà trình duyệt mặc định. Có vẻ như nó thêm một số giá trị cho tôi.
Scott Munro

1
Rời khỏi tên miền null (hoàn toàn không đặt tên miền) KHÔNG khiến Chrome giữ cookie cho localhost. Nó vẫn phớt lờ nó. Lưu ý rằng điều này chỉ áp dụng cho cookie "vĩnh viễn" (những cái đã đặt ngày hết hạn), vì nó sẽ bám vào cookie "phiên" cho localhost (những cái không đặt ngày hết hạn).
Triynko

3

Kết quả tôi đã thay đổi bởi trình duyệt.

Chrome- 127.0.0.1 đã hoạt động nhưng localhost .localhost và "" thì không. Firefox- .localhost đã hoạt động nhưng localhost, 127.0.0.1 và "" thì không.

Chưa được thử nghiệm trong Opera, IE hoặc Safari


3
Chỉ cần thử nghiệm nó với Chrome V.22.0.1229.94 m: Đặt cookie cho localhost mà không cho Domain=tham số hoạt động. Domain=cũng hoạt động, nhưng Domain=localhostkhông.
sleske

3

Đã dành rất nhiều thời gian để khắc phục sự cố này bản thân mình.

Sử dụng PHP và không có gì trên trang này làm việc cho tôi. Cuối cùng tôi đã nhận ra trong mã của mình rằng tham số 'an toàn' đối với session_set_cookie_params () của PHP luôn được đặt thành TRUE.

Vì tôi không truy cập localhost bằng https, trình duyệt của tôi sẽ không bao giờ chấp nhận cookie. Vì vậy, tôi đã sửa đổi phần mã đó của mình thành điều kiện đặt tham số 'an toàn' dựa trên $ _SERVER ['HTTP_HOST'] có phải là 'localhost' hay không. Làm việc tốt bây giờ.

Tôi hi vọng điêu nay se giup được ai đo.


2

Nếu bạn đang đặt cookie từ một tên miền khác (tức là bạn đặt cookie bằng cách thực hiện yêu cầu xuất xứ chéo XHR), thì bạn cần đảm bảo rằng bạn đặt withCredentialsthuộc tính thành true trên XMLHttpRequest mà bạn sử dụng để tìm nạp cookie như được mô tả ở đây


có ngay cả với điều đó. Nó vẫn không hoạt động với các yêu cầu tên miền chéo. Trình duyệt - Safari, IE 11
Rohit Kumar

2

bạn có thể sử dụng localhost.orghoặc đúng hơn là .localhost.orgnó sẽ luôn giải quyết127.0.0.1


1

Tôi đã thử nghiệm may mắn hơn nhiều tại địa phương bằng cách sử dụng 127.0.0.1 làm tên miền. Tôi không chắc tại sao, nhưng tôi đã có kết quả lẫn lộn với localhost và .localhost, v.v.


1

Không có bản sửa lỗi nào được đề xuất cho tôi - đặt nó thành null, false, thêm hai dấu chấm, v.v. - không hoạt động.

Cuối cùng, tôi chỉ xóa tên miền khỏi cookie nếu đó là localhost và hiện tại nó hoạt động với tôi trong Chrome 38 .

Mã trước đó (không hoạt động):

document.cookie = encodeURI(key) + '=' + encodeURI(value) + ';domain=.' + document.domain + ';path=/;';

Mã mới (hiện đang hoạt động):

 if(document.domain === 'localhost') {
        document.cookie = encodeURI(key) + '=' + encodeURI(value) + ';path=/;' ;
    } else {
        document.cookie = encodeURI(key) + '=' + encodeURI(value) + ';domain=.' + document.domain + ';path=/;';
    }

1

Tôi đã có cùng một vấn đề và tôi đã khắc phục nó bằng cách đặt 2 dấu chấm vào tên cookie mà không chỉ định bất kỳ tên miền nào.

set-cookie: name.s1.s2=value; path=/; expires=Sun, 12 Aug 2018 14:28:43 GMT; HttpOnly

1

Dường như có một vấn đề khi bạn sử dụng https://<local-domain>và sau đó http://<local-domain>. Các http://trang web không gửi cookie với các yêu cầu sau khi https://bộ trang web họ. Buộc tải lại và xóa bộ nhớ cache không giúp đỡ. Chỉ xóa thủ công cookie hoạt động. Ngoài ra, nếu tôi xóa chúng trên https://trang, thì http://trang bắt đầu hoạt động trở lại.

Có vẻ như có liên quan đến "Cookie an toàn nghiêm ngặt". Giải thích tốt ở đây . Nó được phát hành trong Chrome 58 vào ngày 2017-04-19.

Thực tế, có vẻ như Chrome thực sự ghi lại cả cookie an toàn và cookie không bảo mật vì nó sẽ hiển thị cookie chính xác tùy thuộc vào giao thức của trang khi nhấp vào biểu tượng trên thanh địa chỉ.

Nhưng Developer tools > Application > Cookiessẽ không hiển thị cookie không bảo mật khi có cookie bảo mật cùng tên cho cùng một tên miền, và cũng sẽ không gửi cookie không bảo mật với bất kỳ yêu cầu nào. Đây có vẻ như là một lỗi của Chrome hoặc nếu hành vi này được mong đợi, cần có một số cách để xem cookie an toàn khi ở trên một httptrang và một dấu hiệu cho thấy chúng đang bị ghi đè.

Giải pháp thay thế là sử dụng các cookie được đặt tên khác nhau tùy thuộc vào việc chúng dành cho trang web http hoặc trang https và đặt tên chúng cụ thể cho ứng dụng của bạn. Một __Secure-tiền tố chỉ ra rằng cookie phải được bảo mật tuyệt đối và cũng là một cách thực hành tốt vì an toàn và không bảo mật sẽ không va chạm. Có những lợi ích khác cho tiền tố quá.

Sử dụng các /etc/hoststên miền khác nhau để truy cập https so với http cũng sẽ hoạt động, nhưng một lần https://localhosttruy cập ngẫu nhiên sẽ ngăn mọi cookie cùng tên hoạt động trên http://localhostcác trang web - vì vậy đây không phải là cách giải quyết tốt.

Tôi đã nộp báo cáo lỗi Chrome .


0

document.cookie = valuename + "=" + value + ";" + hết hạn + "; domain =; path = /";

"tên miền =; đường dẫn = /"; sẽ lấy tên miền động vì cookie của nó sẽ hoạt động trong tên miền phụ. Nếu bạn muốn kiểm tra trong localhost, nó sẽ hoạt động.


0

Không có câu trả lời nào ở đây làm việc cho tôi. Tôi đã sửa nó bằng cách đặt PHP của tôi là điều đầu tiên trong trang.

Giống như các tiêu đề khác, cookie phải được gửi trước bất kỳ đầu ra nào từ tập lệnh của bạn (đây là hạn chế giao thức). Điều này yêu cầu bạn thực hiện các cuộc gọi đến chức năng này trước bất kỳ đầu ra nào, bao gồm và các thẻ cũng như mọi khoảng trắng.

Từ http://php.net/manual/en/feft.setcookie.php


điều đó không liên quan gì đến vấn đề này, đó chỉ là không phạm sai lầm khi gửi bất kỳ đầu ra nào khác trước các tiêu đề
Marnes


0

Tôi đã chơi xung quanh một chút.

Set-Cookie: _xsrf=2|f1313120|17df429d33515874d3e571d1c5ee2677|1485812120; Domain=localhost; Path=/

hoạt động trong Firefox và Chrome như ngày nay. Tuy nhiên, tôi đã không tìm ra cách để làm cho nó hoạt động với curl. Tôi đã thử Host-Header và --resolve, không có may mắn, bất kỳ trợ giúp nào được đánh giá cao.

Tuy nhiên, nó hoạt động trong curl, nếu tôi đặt nó thành

Set-Cookie: _xsrf=2|f1313120|17df429d33515874d3e571d1c5ee2677|1485812120; Domain=127.0.0.1; Path=/

thay thế. (Cái này không hoạt động với Firefox.)


0

Một chi tiết quan trọng khác, hết hạn = nên sử dụng định dạng thời gian ngày sau: Wdy, DD-Mon-YYYY HH: MM: SS GMT ( RFC6265 - Mục 4.1.1 ).

Set-Cookie:
  name=value;
  domain=localhost;
  expires=Thu, 16-07-2019 21:25:05 GMT;
  path=/

5
-1 Thông số kỹ thuật hiện tại cho cookie là RFC 6265, tools.ietf.org/html/rfc6265 , trong đó nêu rõ rằng năm 4 chữ số được phép. Do đó, việc sử dụng năm có 2 chữ số là một ý tưởng tồi, mà các trình duyệt khác nhau sẽ diễn giải khác nhau.
sleske

Chính xác. Tham khảo RFC6265 phần 4.1.1
Giỏ hàng Zen

4
Đúng, nhưng vào tháng 6 năm 2011 tôi đã không tìm thấy RFC này. Vì vậy, trong khi thông tin này không chính xác, trở lại khi tôi viết nó thì không.
Tralamazza

4
Đừng coi đó là một chút, mọi thứ sẽ thay đổi và tất cả chúng ta cần phải giúp đảm bảo rằng câu trả lời luôn hiện hành. Chỉ cần cập nhật câu trả lời của bạn với thông tin mới nhất mà @sleske đã cung cấp cho bạn và cảm ơn sự giúp đỡ của anh ấy.
Matthew Purdon

0

Sau nhiều thử nghiệm và đọc các bài viết khác nhau, điều này đã làm việc. Tôi có thể đặt nhiều cookie, đọc lại và đặt thời gian âm và xóa chúng.

func addCookie(w http.ResponseWriter, name string, value string) {
    expire := time.Now().AddDate(0, 0, 1)
    cookie := http.Cookie{
       Name:    name,
       Value:   value,
       Expires: expire,
       Domain:  ".localhost",
       Path:    "/",
    }
    http.SetCookie(w, &cookie)
}

0

Điều duy nhất làm việc cho tôi là đặt Path=/cookie.

Hơn nữa, giá trị mặc định của thuộc tính đường dẫn dường như khác với trình duyệt với trình duyệt mặc dù tôi chỉ thử nghiệm hai trong số chúng (Firefox và Chrome).

Chrome cố gắng đặt cookie như hiện tại; nếu paththuộc tính được bỏ qua trong Set-Cookietiêu đề thì nó sẽ không được lưu trữ và bỏ qua.

Tuy nhiên, Firefox lưu trữ một cookie ngay cả khi không có paththuộc tính rõ ràng . Nó chỉ đặt nó với đường dẫn được yêu cầu; url yêu cầu của tôi là /api/v1/usersvà đường dẫn được đặt thành /api/v1tự động.

Dù sao, cả hai trình duyệt đều hoạt động khi pathđược đặt thành /ngay cả khi không có tên miền rõ ràng, tức là Domain=localhosthoặc một cái gì đó. Vì vậy, có một số khác biệt trong cách mỗi trình duyệt xử lý cookie.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.