Công thức bánh quy SameSite

Chrome, Firefox, Edge, và các trình duyệt khác đang thay đổi hành vi mặc định theo đề xuất của IETF, Incrementally Better Cookies (Cookie cải tiến từng bước) để:

  • Cookie không có thuộc tính SameSite được coi là SameSite=Lax, nghĩa là hành vi mặc định là chỉ hạn chế cookie trong bối cảnh bên thứ nhất contexts only.
  • Cookie dùng cho nhiều trang web phải chỉ định SameSite=None; Secure để cho phép đưa vào bối cảnh bên thứ ba.

Nếu chưa làm việc này, bạn nên cập nhật các thuộc tính cho cookie của bên thứ ba để chúng không bị chặn trong tương lai.

Browser Support

  • Chrome: 51.
  • Edge: 16.
  • Firefox: 60.
  • Safari: 13.

Trường hợp sử dụng cookie trên nhiều trang web hoặc cookie của bên thứ ba

Có một số trường hợp sử dụng và mẫu phổ biến mà cookie cần được gửi trong bối cảnh bên thứ ba. Nếu bạn cung cấp hoặc phụ thuộc vào một trong những trường hợp sử dụng này, hãy đảm bảo rằng bạn hoặc nhà cung cấp đang cập nhật cookie để dịch vụ hoạt động chính xác.

Nội dung trong <iframe>

Nội dung từ một trang web khác xuất hiện trong <iframe> nằm trong bối cảnh bên thứ ba. Các trường hợp sử dụng tiêu chuẩn bao gồm:

  • Nội dung được nhúng và chia sẻ từ các trang web khác, chẳng hạn như video, bản đồ, mẫu mã và bài đăng trên mạng xã hội.
  • Tiện ích từ các dịch vụ bên ngoài, chẳng hạn như các tính năng thanh toán, lịch, đặt chỗ và đặt trước.
  • Các tiện ích như nút mạng xã hội hoặc dịch vụ chống gian lận tạo ra ít rõ ràng hơn <iframes>.

Cookie có thể được dùng ở đây để duy trì trạng thái phiên, lưu trữ các lựa chọn ưu tiên chung, bật số liệu thống kê hoặc cá nhân hoá nội dung cho người dùng có tài khoản hiện có, cùng với những mục đích khác.

Sơ đồ về một cửa sổ trình duyệt trong đó URL của nội dung được nhúng không khớp với URL của trang.
Nếu nội dung được nhúng không đến từ cùng một trang web với bối cảnh duyệt web ở cấp cao nhất, thì đó là nội dung của bên thứ ba.

Vì web vốn có thể kết hợp được, nên <iframes> cũng được dùng để nhúng nội dung được xem trong bối cảnh ở cấp cao nhất hoặc với tư cách là bên thứ nhất. Mọi cookie mà trang web xuất hiện trong iframe sử dụng đều được coi là cookie của bên thứ ba. Nếu bạn đang tạo các trang web mà bạn muốn các trang web khác nhúng và cần cookie để các trang web đó hoạt động, thì bạn cũng cần đảm bảo rằng các cookie đó được đánh dấu để sử dụng trên nhiều trang web hoặc bạn có thể chuyển sang sử dụng các cookie khác một cách suôn sẻ nếu không có các cookie đó.

Yêu cầu "không an toàn" trên các trang web

"Không an toàn" có thể nghe có vẻ đáng lo ngại ở đây, nhưng nó đề cập đến mọi yêu cầu có thể nhằm mục đích thay đổi trạng thái. Trên web, đó chủ yếu là các yêu cầu POST. Cookie được đánh dấu là SameSite=Lax được gửi trên các lượt điều hướng an toàn ở cấp cao nhất, chẳng hạn như nhấp vào một đường liên kết để chuyển đến một trang web khác. Tuy nhiên, một thao tác như gửi <form> đến một trang web khác bằng cách sử dụng POST sẽ không bao gồm cookie.

Sơ đồ về một yêu cầu di chuyển từ trang này sang trang khác.
Nếu yêu cầu đến sử dụng phương thức "an toàn", thì trang sẽ gửi cookie.

Mẫu này được dùng cho các trang web có thể chuyển hướng người dùng đến một dịch vụ từ xa để thực hiện một số thao tác trước khi quay lại, chẳng hạn như chuyển hướng đến một nhà cung cấp danh tính bên thứ ba. Trước khi người dùng rời khỏi trang web, một cookie sẽ được đặt chứa mã thông báo dùng một lần với kỳ vọng rằng mã thông báo này có thể được kiểm tra trên yêu cầu quay lại để giảm thiểu các cuộc tấn công Giả mạo yêu cầu trên nhiều trang web (CSRF). Nếu yêu cầu quay lại đó được gửi qua POST, thì bạn cần đánh dấu cookie là SameSite=None; Secure.

Tài nguyên từ xa

Mọi tài nguyên từ xa trên một trang, chẳng hạn như từ thẻ <img> hoặc thẻ <script>, có thể dựa vào cookie được gửi kèm theo yêu cầu. Các trường hợp sử dụng phổ biến bao gồm pixel theo dõi và cá nhân hoá nội dung.

Điều này cũng áp dụng cho các yêu cầu được gửi từ JavaScript bằng cách sử dụng fetch hoặc XMLHttpRequest. Nếu fetch() được gọi bằng tuỳ chọn credentials: 'include', thì các yêu cầu đó có thể sẽ bao gồm cookie. Đối với XMLHttpRequest, cookie dự kiến thường được biểu thị bằng withCredentials giá trị fo true. Bạn phải đánh dấu các cookie đó một cách thích hợp để đưa vào các yêu cầu trên nhiều trang web.

Nội dung trong WebView

WebView trong một ứng dụng dành riêng cho nền tảng được hỗ trợ bởi một trình duyệt. Nhà phát triển cần kiểm thử xem các hạn chế hoặc vấn đề ảnh hưởng đến ứng dụng của họ cũng áp dụng cho WebView của ứng dụng hay không.

Android cũng cho phép các ứng dụng dành riêng cho nền tảng đặt cookie trực tiếp bằng cách sử dụng CookieManager API. Giống như cookie được đặt bằng cách sử dụng tiêu đề hoặc JavaScript, hãy cân nhắc việc đưa SameSite=None; Secure vào nếu chúng được dùng cho nhiều trang web.

Cách triển khai SameSite ngay hôm nay

Đánh dấu mọi cookie chỉ cần trong bối cảnh bên thứ nhất là SameSite=Lax hoặc SameSite=Strict tuỳ theo nhu cầu của bạn. Nếu bạn không đánh dấu các cookie này mà dựa vào hành vi mặc định của trình duyệt để xử lý chúng, thì chúng có thể hoạt động không nhất quán trên các trình duyệt và có thể kích hoạt cảnh báo trên bảng điều khiển cho từng cookie.

Set-Cookie: first_party_var=value; SameSite=Lax

Hãy nhớ đánh dấu mọi cookie cần trong bối cảnh bên thứ ba là SameSite=None; Secure. Bạn bắt buộc phải có cả hai thuộc tính. Nếu bạn chỉ chỉ định None mà không có Secure, thì cookie sẽ bị từ chối. Để tính đến sự khác biệt trong quá trình triển khai trình duyệt, bạn có thể cần sử dụng một số chiến lược giảm thiểu được mô tả trong phần Xử lý các ứng dụng không tương thích.

Set-Cookie: third_party_var=value; SameSite=None; Secure

Xử lý các ứng dụng không tương thích

Vì những thay đổi này để đưa None vào và cập nhật hành vi mặc định vẫn còn tương đối mới, nên các trình duyệt khác nhau sẽ xử lý chúng theo những cách khác nhau. Bạn có thể tham khảo trang cập nhật trên chromium.org để xem danh sách các vấn đề đã biết, nhưng danh sách này có thể chưa đầy đủ.

Một giải pháp có thể là đặt từng cookie theo cả kiểu mới và kiểu cũ:

Set-cookie: 3pcookie=value; SameSite=None; Secure
Set-cookie: 3pcookie-legacy=value; Secure

Các trình duyệt triển khai hành vi mới hơn sẽ đặt cookie có giá trị SameSite. Các trình duyệt không triển khai hành vi mới sẽ bỏ qua giá trị đó và đặt cookie 3pcookie-legacy. Khi xử lý các cookie được đưa vào, trang web của bạn trước tiên phải kiểm tra sự hiện diện của kiểu cookie mới, sau đó chuyển về cookie cũ nếu không tìm thấy cookie mới.

Ví dụ sau đây cho biết cách thực hiện việc này trong Node.js, bằng cách sử dụng khung Express và phần mềm trung gian cookie-parser:

const express = require('express');
const cp = require('cookie-parser');
const app = express();
app.use(cp());

app.get('/set', (req, res) => {
  // Set the new style cookie
  res.cookie('3pcookie', 'value', { sameSite: 'none', secure: true });
  // And set the same value in the legacy cookie
  res.cookie('3pcookie-legacy', 'value', { secure: true });
  res.end();
});

app.get('/', (req, res) => {
  let cookieVal = null;

  if (req.cookies['3pcookie']) {
    // check the new style cookie first
    cookieVal = req.cookies['3pcookie'];
  } else if (req.cookies['3pcookie-legacy']) {
    // otherwise fall back to the legacy cookie
    cookieVal = req.cookies['3pcookie-legacy'];
  }

  res.end();
});

app.listen(process.env.PORT);

Phương pháp này yêu cầu bạn phải thực hiện thêm công việc đặt cookie dư thừa và thay đổi tại thời điểm đặt và đọc cookie. Tuy nhiên, phương pháp này sẽ áp dụng cho tất cả các trình duyệt bất kể hành vi của chúng và giúp cookie của bên thứ ba hoạt động.

Ngoài ra, bạn có thể phát hiện ứng dụng bằng cách sử dụng chuỗi tác nhân người dùng khi tiêu đề Set-Cookie được gửi. Tham khảo danh sách các ứng dụng không tương thích, và sử dụng thư viện phát hiện tác nhân người dùng thích hợp cho nền tảng của bạn, chẳng hạn như thư viện ua-parser-js trên Node.js. Phương pháp này chỉ yêu cầu bạn thực hiện một thay đổi, nhưng việc phát hiện tác nhân người dùng có thể không phát hiện được tất cả người dùng bị ảnh hưởng.

Hỗ trợ SameSite=None trong các ngôn ngữ, thư viện và khung

Phần lớn các ngôn ngữ và thư viện đều hỗ trợ thuộc tính SameSite cho cookie. Tuy nhiên, vì việc thêm SameSite=None vẫn còn tương đối mới, nên hiện tại bạn có thể cần giải quyết một số hành vi tiêu chuẩn. Các hành vi này được ghi lại trong kho lưu trữ ví dụ SameSite trên GitHub.

Nhận trợ giúp

Cookie được dùng ở mọi nơi trên web và hiếm khi có nhóm phát triển nào có kiến thức đầy đủ về nơi trang web của họ đặt và sử dụng cookie, đặc biệt là trong các trường hợp sử dụng trên nhiều trang web. Khi bạn gặp phải một vấn đề, có thể đây là lần đầu tiên có người gặp phải vấn đề đó, vì vậy, đừng ngần ngại liên hệ: