Kiểm soát các tính năng của trình duyệt bằng Chính sách 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 về 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 mà một trang, iframe và tài nguyên phụ của trang đó có thể sử dụng 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ó 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 giống nhau và nguồn gốc chéo, đồ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ền quyết định cuối cùng về việc cho phép truy cập vào các tính năng mạnh mẽ hơn và cần phải cấp quyền rõ ràng bằng cách chấp nhận một lời nhắc.

Permissions Policy cho phép trang web cấp cao nhất xác định những gì trang web đó và các bên thứ ba dự định sử dụng, đồng thời giúp người dùng không phải xác định xem yêu cầu truy cập vào tính năng có hợp lệ hay không. Ví dụ: bằng cách sử dụng Chính sách về quyền để chặn tính năng định vị địa lý cho tất cả các bên thứ ba, 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 tính năng định vị địa lý của người dùng.

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

Trước đây, Chính sách về quyền có tên là Chính sách về 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.

Sử dụng các 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á việc phân tích cú pháp và chuyển đổi tuần tự các giá trị 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ả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 khi có Feature Policy.

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 iframe allow

Với Chính sách về tính năng, bạn có thể thêm tính năng này vào một khung hình trên 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 một thuộc tính allow vào thẻ iframe. Với Chính sách về quyền, nếu bạn thêm một khung hình trên nhiều nguồn vào danh sách nguồn, thì thẻ iframe cho nguồn đó phải có 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 vào tính năng này.

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

Bạn vẫn có thể sử dụng Feature Policy sau Chrome 88, nhưng chính sách này sẽ đóng vai trò là một bí danh cho Permissions Policy. Ngoài cú pháp, không có sự khác biệt nào về logic. Nếu bạn sử dụng cả tiêu đề Chính sách về quyền và Chính sách về tính năng, 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 đi sâu vào vấn đề này, hãy xem xét nhanh một tình huống phổ biến, đó là 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ũng như 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 (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 thông tin vị trí địa lý đối với trang web của mình và trang web đáng tin cậy, chứ 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 một cách rõ ràng cho thẻ iframe của trang web đáng tin cậy:

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

Thông tin tổng quan nhanh về việc sử dụng Chính sách về quyền.

Trong ví dụ này, danh sách nguồn 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ị địa lý. ad.example không được phép sử dụng thông tin vị trí địa lý.

  1. Trang web your-site.example của bạn được phép sử dụng tính năng định vị địa lý khi có sự đồng ý của người dùng.
  2. Một 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 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) chưa đượ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 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 trang web nhưng khác nguồn.
  4. Một iframe trên nhiều nguồn (trusted-site.example) được thêm vào danh sách nguồn 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. Một iframe (trusted-site.example) trên nhiều nguồn được thêm vào danh sách nguồn, không có thuộc tính allow, sẽ không được phép sử dụng tính năng này.
  6. Một iframe trên nhiều nguồn (ad.example) chưa được thêm vào danh sách nguồn sẽ không được phép sử dụng tính năng này, ngay cả khi thuộc tính allow được đưa vào 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 về quyền, sau đó trình duyệt cấp quyền truy cập dựa trên tiêu đề đó.

Permissions-Policy: <feature>=(<token>|<origin(s)>)

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

Nếu tiêu đề của bạn 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 gốc bằng dấu cách. Đối với các tiêu đề liệt kê một nguồn gốc là yêu cầu trên nhiều nguồn gốc, thẻ iframe phải có thuộc tính allow.

Sau đây là một số cặp khoá-giá trị mẫu:

  • Cú pháp: [FEATURE]=*
    • Chính sách áp dụng cho tất cả các nguồn
    • Ví dụ: geolocation=*
  • Cú pháp: [FEATURE]=(self)
    • Chính sách á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à các nguồn gốc được chỉ định
    • Ví dụ: geolocation=(self "https://a.example" "https://b.example")
    • self là cách 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à các nguồn gốc đượ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 phải là nguồn của ứng dụng nhúng. Nếu trang nhúng không được cấp quyền, thì các iframe được nhúng trong trang đó cũng sẽ bị chặn mặc dù chúng được thêm vào danh sách nguồn gốc vì Chính sách về quyền uỷ quyền. Bạn cũng có thể dùng mã thông báo self.
  • Cú pháp: [FEATURE]=()
    • Tính năng này không hoạt động đối với mọi nguồn gốc
    • Ví dụ: geolocation=()

Các 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 trang web nhưng khác nguồn gốc. Do đó, việc thêm một 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 một trang web. Bạn phải thêm riêng từng miền con được nhúng muốn sử dụng tính năng này vào danh sách nguồn. Ví dụ: nếu chỉ cho 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 phụ khác của cùng một trang web, https://subdomain.your-site.example, sẽ không có quyền truy cập vào các chủ đề.

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

Thuộc tính allow của iframe

Thiết lập iframe

Để sử dụng trên nhiều nguồn, iframe cần có thuộc tính allow trong thẻ để có quyền truy cập vào 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ý thao tác di chuyển trong iframe

Thiết lập chế độ di chuyển trong 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 chuyển đến. Bằng cách liệt kê nguồn gốc mà iframe chuyển đến trong thuộc tính allow, Permissions Policy (Chính sách về quyền) đã được á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ể xem ví dụ 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ề các chế độ thiết lập sau 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 phép cho tất cả các nguồn gốc có trên trang, bao gồm cả chính trang đó và tất cả các iframe. Trong ví dụ này, tất cả mã được phân phát từ https://your-site.example và 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ị địa lý trong trình duyệt của người dùng. Xin lưu ý rằng bạn cũng phải đặt thuộc tính allow 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 chế độ thiết lập này trong bản minh hoạ.

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

Cấu trúc chỉ cho phép cùng nguồn gốc 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 dữ liệu định vị vị trí cho cùng một nguồn. Các nguồn gốc chéo sẽ không có quyền 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 dữ liệu định vị vị trí. Hãy sử dụng cú pháp này nếu bạn chỉ muốn tính năng này xuất hiện trên trang của mình và không ai khác.

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

Tính năng được phép trên cùng nguồn gốc và các nguồn gốc chéo cụ thể

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

Tính năng này không hoạt động trên mọi nguồn

Cấu trúc của tất cả các nguồn bị chặn truy cập vào tính năng này

Permissions-Policy: geolocation=()

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

Sử dụng API JavaScript

API JavaScript hiện có của Chính sách về tính năng được tìm thấy 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). API JavaScript cho Chính sách về quyền chưa được triển khai.

Bạn có thể dùng Feature Policy API cho các chính sách do Permissions Policy đặt ra, nhưng có một số hạn chế. Vẫn còn những câu hỏi liên quan đến việc triển khai JavaScript API và một đề xuất đã được đưa ra để chuyển logic vào Permissions API. Hãy tham gia thảo luận nếu bạn có ý kiến.

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ả hai chính sách do Chính sách về quyền và Chính sách về tính năng trước đây đặt ra
  • Khi allowsFeature() được gọi trên một phần tử iframe (iframeEl.featurePolicy.allowsFeature('geolocation')), giá trị được trả về sẽ phản ánh việc thuộc tính allow có được đặt trên iframe hay không

featurePolicy.allowsFeature(feature, origin)

  • Trả về true nếu tính năng này được phép cho nguồn gốc đã chỉ định.
  • Nếu phương thức được gọi trên document, thì phương thức này sẽ không cho bạn biết liệu tính năng có được phép cho nguồn gốc đã chỉ định hay không như Feature Policy. Giờ đây, phương thức này cho bạn biết rằng tính năng có thể được phép truy cập vào nguồn gốc đó. Bạn phải tiến hành kiểm tra thêm xem iframe có đặt thuộc tính allow hay không. Nhà phát triển phải tiến hành kiểm tra thêm 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 bên thứ ba hay không.

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

Bạn có thể sử 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).

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 nguồn gốc mặc định.
  • Hành vi này giống nhau đối với cả hai chính sách do Chính sách về quyền và Chính sách về tính năng đặt ra
  • Khi nút được liên kết là một iframe, thuộc tính allow sẽ được xem xét.

featurePolicy.features()

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

Tích hợp Chrome DevTools

Tích hợp Chrome DevTools với Chính sách về quyền

Tìm hiểu 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ụ cho nhà phát triển của Chrome.
  2. Mở bảng điều khiển Application (Ứ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 hình.
  3. Trong thanh bên, hãy chọn khung hình 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ừ Feature-Policy

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

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

Vì tiêu đề Chính sách về tính năng chỉ được hỗ trợ trong các 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ể cập nhật các 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 khi có Feature Policy.

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 phép cho 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) tính đến thuộc tính cho phép, trong khi document.allowsFeature(feature, origin) thì không.

Kiểm tra quyền sử dụng tính năng bằng document

Để tiếp tục sử dụng document làm nút cơ sở, bạn phải thực hiện thêm một bước kiểm tra 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

Reporting API cung cấp một cơ chế báo cáo cho các ứng dụng web theo cách nhất quán và Reporting API cho lỗi vi phạm Chính sách về quyền có sẵn dưới dạng một tính năng thử nghiệm.

Nếu bạn muốn kiểm thử 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 bật cờ này, 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 minh hoạ cách tạo tiêu đề Reporting API:

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 quá trình 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 về mọi lỗi vi phạm xảy ra trong khung đó bằng cách định cấu hình một điểm cuối có tên là "default" (mặc định) như ví dụ trước. Khung phụ sẽ cần có 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: