Kiểm soát các tính năng của trình duyệt bằng Chính sách về quyền

Quản lý cách trang của bạn và iframe của bên thứ ba trên trang của bạn có quyền truy cập vào các tính năng của trình duyệt.

Kevin K. Lee
Kevin K. Lee

Chính sách về quyền (trước đây gọi là Chính sách tính năng) cho phép nhà phát triển kiểm soát các tính năng của trình duyệt có sẵn trên một trang, iframe và tài nguyên phụ của trang đó bằng cách khai báo một bộ chính sách để trình duyệt thực thi. Các chính sách này được áp dụng cho các nguồn gốc được cung cấp trong danh sách nguồn gốc của tiêu đề phản hồi. Danh sách nguồn gốc có thể chứa các nguồn gốc và/hoặc nhiều nguồn gốc, đồng thời cho phép nhà phát triển kiểm soát quyền truy cập của bên thứ nhất và bên thứ ba vào các tính năng của trình duyệt.

Người dùng có quyết định cuối cùng là cho phép sử dụng các tính năng mạnh mẽ hơn và cần cấp quyền rõ ràng thông qua lời nhắc.

Chính sách về quyền cho phép trang web cấp cao nhất xác định nội dung mà trang web và các bên thứ ba dự định sử dụng, đồng thời loại bỏ gánh nặng cho người dùng trong việc xác định xem yêu cầu quyền truy cập tính năng có hợp pháp hay không. Ví dụ: bằng cách chặn tính năng định vị vị trí cho tất cả bên thứ ba thông qua Chính sách về quyền, nhà phát triển có thể chắc chắn rằng không có bên thứ ba nào có quyền truy cập vào thông tin vị trí của người dùng.

Các thay đổi đối với chính sách về quyền

Chính sách về quyền trước đây được gọi là Chính sách tính năng. Các khái niệm chính vẫn giữ nguyên, nhưng có một số thay đổi quan trọng cùng với tên gọi.

Cách sử dụng trường có cấu trúc

Trường có cấu trúc cung cấp một tập hợp các cấu trúc dữ liệu phổ biến để chuẩn hoá quá trình phân tích cú pháp và chuyển đổi tuần tự các giá trị của trường tiêu đề HTTP. Tìm hiểu thêm về Trường có cấu trúc trong bài đăng trên blog của Fastly có tên "Cải thiện HTTP bằng các trường tiêu đề có cấu trúc".

  geolocation 'self' https://example.com; camera 'none'

Trước bằng Chính sách tính năng.

Mới
  geolocation=(self "https://example.com"), camera=()

Nay đã có Chính sách về quyền.

Kết hợp tiêu đề với thuộc tính allow của iframe

Với Chính sách tính năng, bạn có thể thêm tính năng này vào khung nhiều nguồn gốc bằng cách thêm nguồn gốc vào danh sách nguồn gốc của tiêu đề hoặc thêm thuộc tính allow vào thẻ iframe. Theo Chính sách về quyền, nếu bạn thêm một khung trên nhiều nguồn gốc vào danh sách nguồn gốc, thì thẻ iframe cho nguồn gốc đó phải bao gồm thuộc tính allow. Nếu phản hồi không chứa tiêu đề Chính sách về quyền, thì danh sách nguồn gốc được coi là có giá trị mặc định là *. Việc thêm thuộc tính allow vào iframe sẽ cho phép truy cập tính năng này.

Do đó, nhà phát triển nên đặt tiêu đề Chính sách quyền một cách rõ ràng trong phản hồi để chặn các iframe nhiều nguồn gốc không được liệt kê trong danh sách nguồn gốc truy cập vào tính năng này, ngay cả khi có allow.

Sau Chrome 88, bạn vẫn có thể sử dụng Chính sách tính năng nhưng chính sách này đóng vai trò là biệt hiệu của Chính sách về quyền. Ngoài cú pháp, không có khác biệt về logic. Nếu bạn sử dụng cả tiêu đề Chính sách quyền và Chính sách tính năng cùng nhau, thì tiêu đề Permissions-Policy sẽ có mức độ ưu tiên cao hơn và sẽ ghi đè giá trị do tiêu đề Feature-Policy cung cấp.

Làm cách nào để sử dụng Chính sách về quyền?

Tổng quan nhanh

Trước khi tìm hiểu kỹ hơn, hãy cùng xem qua một trường hợp phổ biến khi bạn là chủ sở hữu của một trang web và bạn muốn kiểm soát cách trang web của mình cũng như đoạn mã của bên thứ ba sử dụng các tính năng của trình duyệt.

  • Trang web của bạn là https://your-site.example.
  • Trang web của bạn nhúng một iframe từ cùng nguồn gốc (https://your-site.example).
  • Trang web của bạn nhúng một iframe từ https://trusted-site.example mà bạn tin tưởng.
  • Trang web của bạn cũng hiển thị quảng cáo do https://ad.example phân phát.
  • Bạn chỉ muốn cho phép vị trí địa lý cho trang web của mình và trang web đáng tin cậy, không phải cho quảng cáo.

Trong trường hợp này, hãy sử dụng tiêu đề sau:

Permissions-Policy: geolocation=(self "https://trusted-site.example")

Và đặt thuộc tính allow thành thẻ iframe cho trang web đáng tin cậy một cách rõ ràng:

<iframe src="https://trusted-site.example" allow="geolocation">

Sơ đồ tổng quan nhanh về việc sử dụng Chính sách quyền.

Trong ví dụ này, danh sách nguồn gốc tiêu đề chỉ cho phép trang web của bạn (self) và trusted-site.example sử dụng tính năng định vị vị trí. ad.example không được phép sử dụng tính năng định vị vị trí.

  1. Trang web your-site.example của bạn được phép sử dụng tính năng định vị vị trí khi có sự đồng ý của người dùng.
  2. Iframe cùng nguồn gốc (your-site.example) được phép sử dụng tính năng này mà không cần sử dụng thuộc tính allow.
  3. Một iframe được phân phát từ một miền con khác (subdomain.your-site-example) không được thêm vào danh sách nguồn gốc và có thuộc tính cho phép được đặt trên thẻ iframe, sẽ bị chặn sử dụng tính năng này. Các miền con khác nhau được coi là cùng một trang web nhưng trên nhiều nguồn gốc.
  4. Một iframe nhiều nguồn gốc (trusted-site.example) đã được thêm vào danh sách nguồn gốc và có thuộc tính allow được đặt trên thẻ iframe được phép sử dụng tính năng này.
  5. Iframe nhiều nguồn gốc (trusted-site.example) được thêm vào danh sách nguồn gốc mà không có thuộc tính allow, sẽ bị chặn sử dụng tính năng này.
  6. Một iframe nhiều nguồn gốc (ad.example) không được thêm vào danh sách nguồn gốc sẽ bị chặn sử dụng tính năng này, ngay cả khi thuộc tính allow có trong thẻ iframe.

Tiêu đề phản hồi HTTP Permissions-Policy

Người dùng đưa ra yêu cầu, máy chủ phản hồi bằng tiêu đề Chính sách quyền, sau đó trình duyệt sẽ cấp quyền truy cập dựa trên tiêu đề đó.

Permissions-Policy: &lt;feature&gt;=(&lt;token&gt;|&lt;origin(s)&gt;)

Sử dụng tiêu đề Permissions-Policy trong phản hồi từ máy chủ để đặt các nguồn gốc được phép cho một tính năng. Giá trị tiêu đề có thể kết hợp mã thông báo và chuỗi nguồn gốc. Các mã thông báo hiện có* cho tất cả các nguồn gốc và self cho cùng một nguồn gốc.

Nếu tiêu đề của bạn là dành cho nhiều tính năng, hãy phân tách các tính năng bằng dấu phẩy. Nếu bạn liệt kê nhiều nguồn gốc, hãy phân tách từng nguồn gốc trong danh sách nguồn bằng dấu cách. Đối với tiêu đề liệt kê nguồn gốc là một yêu cầu nhiều nguồn gốc, thẻ iframe phải bao gồm thuộc tính allow.

Dưới đây là một số ví dụ về cặp khoá-giá trị:

  • Cú pháp: [FEATURE]=*
    • Chính sách áp dụng cho mọi nguồn gốc
    • Ví dụ: geolocation=*
  • Cú pháp: [FEATURE]=(self)
    • Chính sách được áp dụng cho cùng nguồn gốc
    • Ví dụ: geolocation=(self)
  • Cú pháp: [FEATURE]=(self [ORIGIN(s)])
    • Chính sách được áp dụng cho cùng nguồn gốc và nguồn gốc đã chỉ định
    • Ví dụ: geolocation=(self "https://a.example" "https://b.example")
    • self là viết tắt của https://your-site.example
  • Cú pháp: [FEATURE]=([ORIGIN(s)])
    • Chính sách được áp dụng cho cùng nguồn gốc và nguồn gốc đã chỉ định
    • Ví dụ: geolocation=("https://your-site.example" "https://a.example" "https://b.example")
    • Khi sử dụng cú pháp này, một trong các nguồn gốc phải là nguồn gốc của trình nhúng. Nếu chính trang trình nhúng không được cấp quyền, các iframe được nhúng trong trang đó cũng sẽ bị chặn ngay cả khi các iframe này được thêm vào danh sách nguồn gốc do Chính sách quyền truy cập uỷ quyền quyền. Bạn cũng có thể sử dụng mã thông báo self.
  • Cú pháp: [FEATURE]=()
    • Tính năng bị chặn đối với mọi gốc
    • Ví dụ: geolocation=()

Miền con và đường dẫn khác nhau

Các miền con khác nhau, chẳng hạn như https://your-site.examplehttps://subdomain.your-site.example, được coi là cùng một trang web nhưng nhiều nguồn gốc. Do đó, việc thêm miền con vào danh sách nguồn gốc sẽ không cho phép truy cập vào một miền con khác của cùng trang web. Tất cả miền con được nhúng muốn sử dụng tính năng này phải được thêm riêng vào danh sách gốc. Ví dụ: nếu chỉ được phép truy cập vào các chủ đề duyệt web của người dùng có cùng nguồn gốc với tiêu đề Permissions-Policy: browsing-topics=(self), thì iframe từ một miền con khác của cùng trang web là https://subdomain.your-site.example sẽ không có quyền truy cập vào chủ đề đó.

Các đường dẫn khác nhau, chẳng hạn như https://your-site.examplehttps://your-site.example/embed, được xem là cùng nguồn gốc và các đường dẫn khác nhau không cần được liệt kê trong danh sách nguồn gốc.

Thuộc tính allow của Iframe

Thiết lập iframe

Để sử dụng nhiều nguồn gốc, iframe cần thuộc tính allow trong thẻ để có quyền sử dụng tính năng này.

Cú pháp: <iframe src="[ORIGIN]" allow="[FEATURE] <'src' | [ORIGIN(s)]"></iframe>

Ví dụ:

<iframe src="https://trusted-site.example" allow="geolocation">

Xử lý hoạt động điều hướng trong iframe

Thiết lập thành phần điều hướng iframe

Theo mặc định, nếu một iframe chuyển đến một nguồn gốc khác, thì chính sách này sẽ không được áp dụng cho nguồn gốc mà iframe đó điều hướng đến. Bằng cách liệt kê nguồn gốc mà iframe chuyển đến trong thuộc tính allow, Chính sách về quyền đã áp dụng cho iframe ban đầu sẽ được áp dụng cho nguồn gốc mà iframe chuyển đến.

<iframe src="https://trusted-site.example" allow="geolocation https://trusted-site.example https://trusted-navigated-site.example">

Bạn có thể thấy tính năng này trong thực tế bằng cách truy cập vào bản minh hoạ điều hướng iframe.

Ví dụ về cách thiết lập Chính sách về quyền

Bạn có thể xem ví dụ về những cách thiết lập sau đây trong bản minh hoạ.

Tính năng được phép trên mọi nguồn gốc

Cấu trúc của tất cả các nguồn gốc được phép truy cập vào tính năng này

Permissions-Policy: geolocation=*
<iframe src="https://trusted-site.example" allow="geolocation">
<iframe src="https://ad.example" allow="geolocation">

Khi danh sách nguồn gốc được đặt thành mã thông báo *, tính năng này được cho phép đối với mọi nguồn gốc có trên trang, bao gồm chính nó và tất cả iframe. Trong ví dụ này, tất cả các mã được phân phối từ https://your-site.example và các mã được phân phát từ iframe https://trusted-site.examplehttps://ad.example đều có quyền truy cập vào tính năng định vị vị trí trong trình duyệt của người dùng. Hãy nhớ rằng thuộc tính cho phép cũng phải được đặt trên chính iframe cùng với việc thêm nguồn gốc vào danh sách nguồn gốc của tiêu đề.

Bạn có thể xem cách thiết lập này trong bản minh hoạ.

Tính năng chỉ được phép sử dụng trên cùng nguồn gốc

Cấu trúc có cùng một nguồn gốc được phép truy cập vào tính năng

Permissions-Policy: geolocation=(self)

Việc sử dụng mã thông báo self chỉ cho phép sử dụng vị trí địa lý cho cùng một nguồn gốc. Các nguồn gốc khác sẽ không thể sử dụng tính năng này. Trong ví dụ này, chỉ https://trusted-site.example (self) mới có quyền truy cập vào thông tin định vị vị trí. Sử dụng cú pháp này nếu bạn chỉ muốn dùng tính năng đó cho trang của mình chứ không muốn áp dụng cho ai khác.

Bạn có thể xem cách thiết lập này trong bản minh hoạ.

Tính năng được cho phép trên cùng một nguồn gốc và nhiều nguồn gốc cụ thể

Cấu trúc của các nguồn gốc đã chỉ định được phép truy cập vào tính năng này

Permissions-Policy: geolocation=(self "https://trusted-site.example")

Cú pháp này cho phép sử dụng vị trí địa lý cho cả chính mình (https://your-site.example) và https://trusted-site.example. Hãy nhớ thêm thuộc tính cho phép vào thẻ iframe một cách rõ ràng. Nếu có một iframe khác với <iframe src="https://ad.example" allow="geolocation">, https://ad.example sẽ không có quyền truy cập vào tính năng định vị vị trí. Chỉ trang gốc và https://trusted-site.example được liệt kê trong danh sách nguồn gốc cùng với việc có thuộc tính cho phép trong thẻ iframe mới có quyền truy cập vào tính năng của người dùng.

Bạn có thể xem cách thiết lập này trong bản minh hoạ.

Tính năng bị chặn trên mọi nguồn gốc

Cấu trúc của tất cả các nguồn gốc đã bị chặn sử dụng tính năng này

Permissions-Policy: geolocation=()

Khi danh sách nguồn gốc trống, tính năng này sẽ bị chặn đối với mọi nguồn gốc. Bạn có thể xem cách thiết lập này trong bản minh hoạ.

Sử dụng API JavaScript

Đã tìm thấy API JavaScript hiện tại của Chính sách tính năng dưới dạng một đối tượng trên tài liệu hoặc phần tử (document.featurePolicy or element.featurePolicy). Chính sách API JavaScript cho quyền chưa được triển khai.

API Chính sách tính năng có thể được sử dụng cho các chính sách do Chính sách về quyền đặt ra với một số giới hạn. Còn câu hỏi còn lại liên quan đến việc triển khai API JavaScript và đã đưa ra một đề xuất để chuyển logic vào API Quyền. Tham gia thảo luận nếu bạn có bất kỳ ý kiến nào.

featurePolicy.allowsFeature(feature)

  • Trả về true nếu tính năng này được phép sử dụng nguồn gốc mặc định.
  • Hành vi này giống nhau đối với cả chính sách do Chính sách về quyền đặt ra và Chính sách tính năng trước đó
  • Khi allowsFeature() được gọi trên một phần tử iframe (iframeEl.featurePolicy.allowsFeature('geolocation')), giá trị được trả về cho biết thuộc tính allow được đặt trên iframe hay không

featuresPolicy.allowFeature(tính năng, nguồn gốc)

  • Trả về true nếu tính năng này được cho phép đối với nguồn gốc đã chỉ định.
  • Nếu phương thức này được gọi trên document, thì phương thức này sẽ không còn cho bạn biết liệu tính năng có được cho phép đối với nguồn gốc được chỉ định hay không như Chính sách tính năng đã thực hiện. Bây giờ, phương thức này sẽ cho bạn biết rằng đối tượng có thể được cho phép đối với nguồn gốc đó. Bạn phải tiến hành kiểm tra thêm để xem iframe đã đặt thuộc tính allow hay chưa. Nhà phát triển phải tiến hành kiểm tra bổ sung đối với thuộc tính allow trên phần tử iframe để xác định xem tính năng này có được phép dùng cho nguồn gốc của bên thứ ba hay không.

Kiểm tra các tính năng trong iframe với đối tượng element

Bạn có thể dùng element.allowsFeature(feature) có tính đến thuộc tính cho phép, không giống như document.allowsFeature(feature, origin) thì không tính đến.

const someIframeEl = document.getElementById('some-iframe')
const isCameraFeatureAllowed = someIframeEl.featurePolicy.allowsFeature('camera')

featurePolicy.allowedFeatures()

  • Trả về danh sách các tính năng được phép sử dụng theo nguồn gốc mặc định.
  • Hành vi này giống nhau đối với cả chính sách do Chính sách về quyền và Chính sách tính năng đặt ra
  • Khi nút được liên kết là iframe, thuộc tính cho phép sẽ được tính đến.

featurePolicy.features()

  • Trả về danh sách tính năng có trong trình duyệt.
  • Hành vi này giống nhau đối với cả chính sách do Chính sách về quyền và Chính sách tính năng đặt ra

Tích hợp Công cụ của Chrome cho nhà phát triển

Tích hợp Công cụ của Chrome cho nhà phát triển với Chính sách về quyền

Xem cách hoạt động của Chính sách về quyền trong Công cụ cho nhà phát triển.

  1. Mở Công cụ của Chrome cho nhà phát triển.
  2. Mở bảng điều khiển Ứng dụng để kiểm tra các tính năng được phép và không được phép của từng khung.
  3. Trong thanh bên, hãy chọn khung mà bạn muốn kiểm tra. Bạn sẽ thấy danh sách các tính năng mà khung đã chọn được phép sử dụng và danh sách các tính năng bị chặn trong khung đó.

Di chuyển từ chính sách tính năng

Nếu đang sử dụng tiêu đề Feature-Policy, bạn có thể triển khai các bước sau để chuyển sang Chính sách về quyền.

Thay thế tiêu đề Chính sách tính năng bằng tiêu đề Chính sách về quyền

Do tiêu đề Chính sách tính năng chỉ được hỗ trợ trong trình duyệt dựa trên Chromium và tiêu đề Chính sách về quyền được hỗ trợ kể từ Chrome 88, nên bạn có thể yên tâm cập nhật tiêu đề hiện có bằng Chính sách về quyền.

Feature-Policy:
  autoplay *;
  geolocation 'self';
  camera 'self' 'https://trusted-site.example';
  fullscreen 'none';

Trước bằng Chính sách tính năng.

Mới
Permissions-Policy:
  autoplay=*,
  geolocation=(self),
  camera=(self "https://trusted-site.example"),
  fullscreen=()

Nay đã có Chính sách về quyền.

Cập nhật mức sử dụng document.allowsFeature(feature, origin)

Nếu bạn đang sử dụng phương thức document.allowsFeature(feature, origin) để kiểm tra các tính năng được cho phép đối với iframe, hãy sử dụng phương thức allowsFeature(feature) được đính kèm trên phần tử iframe chứ không phải document chứa. Phương thức element.allowsFeature(feature) có tính đến thuộc tính cho phép, còn document.allowsFeature(feature, origin) thì không.

Đang kiểm tra quyền sử dụng tính năng của document

Để tiếp tục sử dụng document làm nút cơ sở, bạn phải tiến hành kiểm tra thêm cho thuộc tính allow trên thẻ iframe.

<iframe id="some-iframe" src="https://example.com" allow="camera"></iframe>
Permissions-Policy: camera=(self "https://example.com")
const isCameraPolicySet = document.featurePolicy.allowsFeature('camera', 'https://example.com')

const someIframeEl = document.getElementById('some-iframe')
const hasCameraAttributeValue = someIframeEl.hasAttribute('allow')
&& someIframeEl.getAttribute('allow').includes('camera')

const isCameraFeatureAllowed = isCameraPolicySet && hasCameraAttributeValue

Thay vì cập nhật mã hiện có bằng document, bạn nên gọi allowsFeature() trên đối tượng element như ví dụ trước.

API báo cáo

API báo cáo cung cấp cơ chế báo cáo cho các ứng dụng web một cách nhất quán và API báo cáo cho các trường hợp vi phạm chính sách về quyền được cung cấp dưới dạng tính năng thử nghiệm.

Nếu bạn muốn kiểm tra tính năng thử nghiệm này, hãy làm theo hướng dẫn và bật cờ trong chrome://flags/#enable-experimental-web-platform-features. Khi cờ bật, bạn có thể quan sát các lỗi vi phạm Chính sách về quyền trong Công cụ cho nhà phát triển trong thẻ Ứng dụng:

Ví dụ sau đây cho thấy cách tạo tiêu đề API Báo cáo:

Reporting-Endpoints: main-endpoint="https://reports.example/main", default="https://reports.example/default"

Content-Security-Policy: script-src 'self'; object-src 'none'; report-to main-endpoint;
Document-Policy: document-write=?0; report-to=main-endpoint;

Trong cách triển khai hiện tại, bạn có thể nhận được báo cáo vi phạm chính sách từ mọi lỗi vi phạm xảy ra trong khung đó bằng cách thiết lập điểm cuối có tên "mặc định" như ví dụ trên. Khung phụ sẽ yêu cầu cấu hình báo cáo riêng.

Tìm hiểu thêm

Để hiểu rõ hơn về Chính sách về quyền, hãy tham khảo các tài nguyên sau: