Làm thế nào để xử lý nhiều cookie có cùng tên?


92

Ví dụ: tôi có một ứng dụng gửi các tiêu đề HTTP sau để đặt thành cookie có tên "a":

Set-Cookie: a=1;Path=/;Version=1
Set-Cookie: a=2;Path=/example;Version=1

Nếu tôi truy cập /exampletrên máy chủ thì cả hai đường dẫn đều hợp lệ, vì vậy tôi có hai cookie tên là "a"! Vì trình duyệt không gửi bất kỳ thông tin đường dẫn nào nên không thể phân biệt được hai cookie.

Cookie: a=2; a=1

Trường hợp này phải xử lý như thế nào? Chọn cái đầu tiên? Tạo một danh sách với tất cả các giá trị cookie? Hay trường hợp như vậy nên được coi là sai lầm của nhà phát triển?


Tôi sẽ cố gắng hết sức (đọc: mọi thứ tôi có thể) để tránh trùng lặp tên cookie. Hầu hết mọi người chưa bao giờ gặp phải vấn đề này - vì lý do chính đáng.

Trang web chỉ có thể đọc cookie của chính nó. Nó không thể đọc cookie của trang web / miền khác. Bảo mật này được đảm bảo bởi trình duyệt. Đây có thể là một mẹo cho người mới bắt đầu tuyệt đối (tôi đã có sự nhầm lẫn này)
Arun

Câu trả lời:


38

Từ bài viết này trên SitePoint :

Nếu nhiều cookie có cùng tên khớp với một URI yêu cầu nhất định, thì một cookie sẽ được trình duyệt chọn.

Đường dẫn càng cụ thể thì mức độ ưu tiên càng cao. Tuy nhiên, mức độ ưu tiên dựa trên các thuộc tính khác, bao gồm cả miền, là không xác định và có thể khác nhau giữa các trình duyệt. Điều này có nghĩa là nếu bạn đã đặt cookie cùng tên cho “.example.org” và “www.example.org”, bạn không thể chắc chắn cái nào sẽ được gửi lại.

Chỉnh sửa: thông tin này từ năm 2010 dường như đã lỗi thời, có vẻ như các trình duyệt hiện có thể gửi lại nhiều cookie, hãy xem câu trả lời của @Nate bên dưới để biết chi tiết


9
Vậy làm cách nào để xóa nhiều cookie giống nhau? Tôi đã nghiên cứu điều này hai ngày nay và các cookie trùng lặp dường như không thể phá hủy được.
Bob Jones

13
@Brant Bài viết đó có thể hơi không chính xác - Tôi vừa thấy Chrome gửi lại hai cookie cùng tên (nhưng đường dẫn khác nhau), vì vậy "một cookie được chọn bởi trình duyệt" không nhất thiết là đúng. Cookie đường dẫn sâu nhất đã được gửi đầu tiên, BTW, điều này có vẻ hợp lý. Và một chiếc bánh quy khác cũng ở giữa.
Jonas N

3
Firefox (15) cũng gửi hai cookie có cùng tên! nếu nó gặp phải với hai cookie với cho tên miền .a.comvà máy chủa.com
Taha Jahangir

Quả thực thông tin này là sai. Câu trả lời của @Nate nếu tôi được đánh dấu là đúng.
Dan Milon

4
404: Không tìm thấy câu trả lời của @ Nate nổi tiếng.
d.popov

90

Câu trả lời đề cập đến một bài báo trên SitePoint không hoàn toàn đầy đủ. Vui lòng xem RFC 6265 (công bằng mà nói, RFC này được phát hành vào năm 2011 sau khi câu hỏi này được đăng, thay thế RFC 2965 trước đó từ năm 2000 và RFC 2109 từ năm 1997).

Phần 5.4 , tiểu mục 2 có điều này để nói:

Tác nhân người dùng NÊN sắp xếp danh sách cookie theo thứ tự sau:

  • Cookie có đường dẫn dài hơn được liệt kê trước cookie có đường dẫn ngắn hơn.

LƯU Ý: Không phải tất cả các tác nhân người dùng đều sắp xếp danh sách cookie theo thứ tự này, nhưng thứ tự này phản ánh thông lệ phổ biến khi tài liệu này được viết, và trong lịch sử, đã có những máy chủ (sai) phụ thuộc vào thứ tự này.

Ngoài ra còn có viên ngọc nhỏ này trong phần 4.2.2 :

... máy chủ KHÔNG NÊN dựa vào thứ tự tuần tự hóa. Đặc biệt, nếu tiêu đề Cookie chứa hai cookie có cùng tên (ví dụ: được đặt với các thuộc tính Đường dẫn hoặc Miền khác nhau), máy chủ KHÔNG NÊN dựa vào thứ tự mà các cookie này xuất hiện trong tiêu đề.

Trong cookie yêu cầu mẫu của bạn ( Cookie: a = 2; a = 1 ) lưu ý rằng cookie được đặt với đường dẫn / example ( a = 2 ) có đường dẫn dài hơn so với cookie có đường dẫn / ( a = 1 ) và do đó được gửi lại cho bạn trong dòng đầu tiên, phù hợp với khuyến nghị của thông số kỹ thuật. Vì vậy, bạn ít nhiều đúng khi cho rằng bạn có thể chọn giá trị đầu tiên.

Thật không may, ngôn ngữ được sử dụng trong RFC cực kỳ cụ thể - việc sử dụng các từ NÊNKHÔNG NÊN gây ra sự mơ hồ trong RFC. Những điều này chỉ ra các quy ước cần được tuân theo, nhưng không bắt buộc phải tuân theo thông số kỹ thuật. Mặc dù tôi hiểu khá rõ về RFC cho vấn đề này, nhưng tôi vẫn chưa thực hiện nghiên cứu để xem khách hàng trong thế giới thực làm gì; có thể một hoặc nhiều trình duyệt hoặc phần mềm khác hoạt động như máy khách HTTP có thể không gửi cookie đường dẫn dài nhất (ví dụ: / example ) đầu tiên trong tiêu đề Cookie:.

Nếu bạn có quyền kiểm soát giá trị của cookie và bạn muốn làm cho giải pháp của mình trở nên dễ hiểu, tốt nhất bạn nên:

  1. sử dụng tên cookie khác để ghi đè trong các đường dẫn nhất định, chẳng hạn như:

    • Set-cookie: a-global = 1; Path = /; Version = 1
    • Set-cookie: a-example = 2; Đường dẫn = / example; Phiên bản = 1
  2. lưu trữ đường dẫn bạn cần trong chính giá trị cookie:

    • Set-cookie: a = 1 & path = /; Path = /; Phiên bản = 1
    • Set-cookie: a = 2 & path = / example; Path = / example; Phiên bản = 1

Cả hai cách giải quyết này đều yêu cầu logic bổ sung trên máy chủ để chọn giá trị cookie mong muốn, bằng cách so sánh URL được yêu cầu với danh sách cookie có sẵn. Nó không quá đẹp. Thật không may RFC không có tầm nhìn xa để yêu cầu một con đường còn hoàn toàn ghi đè một cookie với một con đường ngắn hơn (ví dụ: trong ví dụ của bạn, bạn sẽ nhận được a = 2: Cookie chỉ ).


2
Cảm ơn bạn đã tìm ra điều này từ những RFC chết tiệt này! // tại sao thậm chí còn bận tâm đọc chúng nếu không ai làm theo những đề xuất này? ..
Rast

3
Có vẻ như Wildfly 8.0 đang chú ý đến thứ tự của các cookie và sử dụng cái đầu tiên. Điều này cho phép chúng tôi chạy một ứng dụng khác trong ngữ cảnh 'lồng nhau'. Tuy nhiên, nó sẽ không thành công nếu một số trình duyệt không tuân theo khuyến nghị của RFC. Cách đúng để thực hiện việc này để đặt tên khác của cookie phiên, như JSESSIONID2.
honzajde

2
Tôi đã kiểm tra các trình duyệt chính sau khi đọc câu trả lời của bạn: Chrome 63 / Opera 55 / IE11 / Edge 16 / Safari 11 / Firefox 58 Và dường như tất cả chúng đều xử lý chính xác rằng Cookie có đường dẫn dài hơn đứng trước Cookie có đường dẫn ngắn hơn. Và trong PHP (được thử nghiệm trên phiên bản 7), nó chỉ đọc cookie đầu tiên được đặt thành biến $ _COOKIE.
Alexander Schranz

1
Liệu path=/;Path=/đặc điểm kỹ thuật chiếu theo FRC-6265? Tôi không tìm thấy đề cập như vậy. Tomcat đe dọa bất kỳ ";" trong đường dẫn là biểu tượng không chính xác
Hubbitus

1
@Hubbitus Hãy chú ý, a=2&path=/example;Path=/examplevì vậy không có ;đường dẫn.
Franklin Yu

2

Không có gì sai khi có nhiều giá trị cho cùng một tên ... nếu bạn muốn chúng. Bạn thậm chí có thể nhúng ngữ cảnh bổ sung vào giá trị.

Nếu bạn không, thì tất nhiên các tên khác nhau là một giải pháp nếu bạn muốn cả hai ngữ cảnh.

Cách thay thế là gửi cùng một tên cookie với cùng một đường dẫn (và tên miền) thậm chí từ các đường dẫn cụ thể hơn. Các hướng dẫn cookie đã đặt đó sẽ ghi đè giá trị của cookie đó.

Bây giờ bạn đã biết phần quan trọng nhất (cách chúng hoạt động) và bạn có thể hoàn thành những gì bạn cần theo một vài cách khác nhau, câu trả lời của tôi cho câu hỏi của bạn là: đây là vấn đề của nhà phát triển.


0

Tôi chắc chắn biết về các ứng dụng làm việc này rộng rãi bằng cách sử dụng nhiều id phiên - và dường như hoạt động nhất quán. Tuy nhiên, tôi không biết - và không có ý định tìm hiểu - nếu họ làm như vậy vì trình duyệt trả về các cookie theo thứ tự nhất quán tùy thuộc vào thời điểm chúng được đặt / đường dẫn chúng được đặt hoặc liệu ứng dụng có cố gắng khớp từng một đến một phiên hiện có.

Tôi thực sự khuyên bạn nên tránh thực hành này.

Tuy nhiên, nếu bạn thực sự muốn biết cách các trình duyệt (và ứng dụng) xử lý tình huống này, tại sao không xây dựng một giàn thử nghiệm và dùng thử.


2
Máy chủ không có quyền kiểm soát những gì được trình duyệt gửi đến nó. Nó vẫn cần được xử lý.
Martin OConnor

0

Nếu bạn sử dụng Java / Scala framework Play: hãy coi chừng! Nếu một yêu cầu chứa nhiều cookie có cùng tên, Play sẽ chỉ hiển thị 1 trong số chúng vào mã của bạn.


-2

Nếu bạn cần phân biệt chúng, bạn phải cung cấp cho chúng các giá trị khóa khác nhau.

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.