Thêm tiêu đề bổ sung của yêu cầu HTTP

Các yêu cầu HTTP chứa các tiêu đề như User-Agent hoặc Content-Type. Ngoài các tiêu đề do trình duyệt đính kèm, các ứng dụng Android có thể thêm tiêu đề bổ sung, chẳng hạn như Cookie hoặc Referrer thông qua phần bổ sung EXTRA_HEADERS của Intent. Vì lý do bảo mật, Chrome sẽ lọc một số tiêu đề bổ sung tuỳ thuộc vào cách thức và vị trí khởi chạy ý định.

Các yêu cầu khác nguồn gốc cần có thêm một lớp bảo mật vì máy khách và máy chủ không thuộc cùng một bên. Hướng dẫn này thảo luận về việc khởi chạy các yêu cầu như vậy thông qua thẻ tuỳ chỉnh của Chrome, tức là các ý định được khởi chạy từ những ứng dụng mở một URL trong thẻ trình duyệt. Cho đến Chrome 83, nhà phát triển có thể thêm mọi tiêu đề khi chạy Thẻ tuỳ chỉnh. Kể từ phiên bản 83, Chrome bắt đầu lọc tất cả các tiêu đề khác nguồn gốc, ngoại trừ các tiêu đề được đưa vào danh sách phê duyệt, vì các tiêu đề không được đưa vào danh sách phê duyệt gây ra rủi ro bảo mật. Kể từ Chrome 86, bạn có thể đính kèm các tiêu đề không nằm trong danh sách phê duyệt vào các yêu cầu khác nguồn gốc, khi máy chủ và ứng dụng có liên quan bằng cách sử dụng đường liên kết đến tài sản kỹ thuật số. Hành vi này được tóm tắt trong bảng sau:

Phiên bản Chrome Tiêu đề CORS được cho phép
trước Chrome phiên bản 83 approvelisted, non-approvelisted
Chrome phiên bản 83 đến 85 được đưa vào danh sách phê duyệt
từ Chrome phiên bản 86 trở đi approvelisted, non-approvelisted khi bạn thiết lập đường liên kết đến tài sản kỹ thuật số

Bảng 1: Lọc các tiêu đề CORS không có trong danh sách được phê duyệt.

Bài viết này hướng dẫn cách thiết lập một kết nối đã xác minh giữa máy chủ và ứng dụng, đồng thời sử dụng kết nối đó để gửi các tiêu đề http có trong danh sách được phê duyệt cũng như không có trong danh sách được phê duyệt. Bạn có thể chuyển đến phần Thêm tiêu đề bổ sung vào ý định của thẻ tuỳ chỉnh để xem mã.

Thông tin khái quát

Tiêu đề yêu cầu CORS được đưa vào danh sách phê duyệt so với tiêu đề yêu cầu CORS không được đưa vào danh sách phê duyệt

Chia sẻ tài nguyên trên nhiều nguồn gốc (CORS) cho phép một ứng dụng web từ một nguồn gốc yêu cầu tài nguyên của một nguồn gốc khác. Danh sách các tiêu đề CORS-approvelisted được duy trì trong Tiêu chuẩn HTML. Bảng tiếp theo cho thấy ví dụ về các tiêu đề trong danh sách được phê duyệt:

Tiêu đề Nội dung mô tả
accept-language quảng cáo ngôn ngữ tự nhiên mà máy khách hiểu
content-language mô tả ngôn ngữ dành cho đối tượng hiện tại
content-type cho biết loại nội dung nghe nhìn của tài nguyên

Bảng 2: Ví dụ về các tiêu đề CORS trong danh sách được phê duyệt.

Các tiêu đề trong danh sách phê duyệt được coi là an toàn vì không chứa thông tin nhạy cảm của người dùng và khó có khả năng khiến máy chủ thực hiện các thao tác có thể gây hại.

Bảng sau đây minh hoạ các ví dụ về tiêu đề không nằm trong danh sách được phê duyệt:

Tiêu đề Nội dung mô tả
bearer-token xác thực ứng dụng tại một máy chủ
nguồn gốc cho biết nguồn gốc của yêu cầu
bánh quy chứa cookie do máy chủ đặt

Bảng 3: Ví dụ về các tiêu đề CORS không nằm trong danh sách được phê duyệt.

Tiêu chuẩn HTML không khuyến khích việc đính kèm các tiêu đề không có trong danh sách được phê duyệt vào các yêu cầu CORS và các máy chủ giả định rằng các yêu cầu khác nguồn gốc chỉ chứa các tiêu đề có trong danh sách được phê duyệt. Việc gửi các tiêu đề không có trong danh sách phê duyệt từ các miền chéo sẽ cho phép các ứng dụng độc hại của bên thứ ba tạo ra các tiêu đề sử dụng sai cookie người dùng mà Chrome (hoặc một trình duyệt khác) lưu trữ và đính kèm vào các yêu cầu. Cookie có thể xác thực các giao dịch máy chủ độc hại mà nếu không có cookie thì không thể thực hiện được.

Đính kèm các tiêu đề được đưa vào danh sách phê duyệt CORS vào các yêu cầu của Thẻ tuỳ chỉnh

Thẻ tuỳ chỉnh là một cách đặc biệt để chạy các trang web trong một thẻ trình duyệt tuỳ chỉnh. Bạn có thể tạo các ý định Thẻ tuỳ chỉnh bằng cách sử dụng CustomTabsIntent.Builder(). Bạn cũng có thể đính kèm tiêu đề vào các ý định này bằng cách sử dụng Bundle với cờ Browser.EXTRA_HEADERS:

CustomTabsIntent intent = new CustomTabsIntent.Builder(session).build();

Bundle headers = new Bundle();
headers.putString("bearer-token", "Some token");
headers.putString("redirect-url", "Some redirect url");   
intent.intent.putExtra(Browser.EXTRA_HEADERS, headers);

intent.launchUrl(Activity.this, Uri.parse("http://www.google.com"));

Chúng ta luôn có thể đính kèm các tiêu đề trong danh sách phê duyệt vào các yêu cầu CORS của thẻ tuỳ chỉnh. Tuy nhiên, theo mặc định, Chrome sẽ lọc các tiêu đề không có trong danh sách phê duyệt. Mặc dù các trình duyệt khác có thể có hành vi khác, nhưng các nhà phát triển nên dự kiến rằng các tiêu đề không nằm trong danh sách phê duyệt sẽ bị chặn nói chung.

Cách được hỗ trợ để đưa các tiêu đề không có trong danh sách phê duyệt vào các thẻ tuỳ chỉnh là trước tiên, hãy xác minh kết nối khác nguồn gốc bằng cách sử dụng một đường liên kết truy cập kỹ thuật số. Phần tiếp theo cho biết cách thiết lập các tiêu đề này và chạy một ý định Thẻ tuỳ chỉnh bằng các tiêu đề bắt buộc.

Thêm tiêu đề bổ sung vào ý định của thẻ tuỳ chỉnh

Để cho phép các tiêu đề không có trong danh sách phê duyệt được truyền qua các ý định của Thẻ tuỳ chỉnh, bạn cần thiết lập một đường liên kết đến tài sản kỹ thuật số giữa ứng dụng Android và ứng dụng web để xác minh rằng tác giả sở hữu cả hai ứng dụng.

Làm theo hướng dẫn chính thức để thiết lập mối liên kết đến tài sản kỹ thuật số. Đối với mối quan hệ liên kết, hãy sử dụng "delegate_permission/common.use_as_origin" cho biết rằng cả hai ứng dụng đều thuộc cùng một nguồn gốc sau khi đường liên kết được xác minh.

Tạo ý định Thẻ tuỳ chỉnh bằng tiêu đề bổ sung

Có nhiều cách để tạo một Custom Tabs intent. Bạn có thể sử dụng trình tạo có trong AndroidX bằng cách thêm thư viện vào các phần phụ thuộc của bản dựng:

implementation 'androidx.browser:browser:1.2.0'

Tạo ý định và thêm tiêu đề bổ sung:

CustomTabsIntent constructExtraHeadersIntent(CustomTabsSession session) {
    CustomTabsIntent intent = new CustomTabsIntent.Builder(session).build();

    // Example non-cors-approvelisted headers.
    Bundle headers = new Bundle();
    headers.putString("bearer-token", "Some token");
    headers.putString("redirect-url", "Some redirect url");
    intent.intent.putExtra(Browser.EXTRA_HEADERS, headers);
    return intent;
}

Kết nối Thẻ tuỳ chỉnh được dùng để thiết lập một CustomTabsSession giữa ứng dụng và thẻ Chrome. Chúng tôi cần phiên này để xác minh rằng ứng dụng và ứng dụng web thuộc cùng một nguồn gốc. Quy trình xác minh chỉ thành công nếu bạn thiết lập đúng các đường liên kết đến tài sản kỹ thuật số.

Bạn nên gọi CustomTabsClient.warmup(). Điều này cho phép ứng dụng trình duyệt khởi tạo trước ở chế độ nền và tăng tốc quá trình mở URL.

// Set up a connection that warms up and validates a session.
CustomTabsServiceConnection connection = new CustomTabsServiceConnection() {
    @Override
    public void onCustomTabsServiceConnected(@NonNull ComponentName name, 
        @NonNull CustomTabsClient client) {
        // Create session after service connected.
        mSession = client.newSession(callback);
        client.warmup(0);
        // Validate the session as the same origin to allow cross origin headers.
        mSession.validateRelationship(CustomTabsService.RELATION_USE_AS_ORIGIN, 
            Uri.parse(url), null);
    }
    @Override
    public void onServiceDisconnected(ComponentName componentName) { }
};

Thiết lập một lệnh gọi lại khởi chạy Ý định sau khi xác thực

CustomTabsCallback đã được truyền vào phiên. Chúng ta thiết lập onRelationshipValidationResult() của nó để chạy CustomTabsIntent đã tạo trước đó sau khi xác minh nguồn gốc thành công.

// Set up a callback that launches the intent after session validated.
CustomTabsCallback callback = new CustomTabsCallback() {
    @Override
    public void onRelationshipValidationResult(int relation, @NonNull Uri requestedOrigin, 
        boolean result, @Nullable Bundle extras) {
        // Launch custom tabs intent after session was validated as the same origin.
        CustomTabsIntent intent = constructExtraHeadersIntent(mSession);
        intent.launchUrl(MainActivity.this, Uri.parse(url));
    }
};

Liên kết kết nối dịch vụ thẻ tuỳ chỉnh

Việc liên kết dịch vụ sẽ khởi chạy dịch vụ và onCustomTabsServiceConnected() của kết nối sẽ được gọi cuối cùng. Đừng quên huỷ liên kết dịch vụ một cách thích hợp. Việc liên kết và huỷ liên kết thường được thực hiện trong các phương thức vòng đời của activity onStart() và onStop().

// Bind the custom tabs service connection.
// Call this in onStart()
CustomTabsClient.bindCustomTabsService(this,
    CustomTabsClient.getPackageName(MainActivity.this, null), connection);

// …
// Unbind the custom tabs service.
// Call this in onStop().
unbindService(connection);

Mã xử lý ứng dụng minh hoạ

Bạn có thể xem thêm thông tin chi tiết về Dịch vụ thẻ tuỳ chỉnh tại đây. Hãy xem kho lưu trữ android-browser-helper trên GitHub để biết một ứng dụng mẫu đang hoạt động.

Tóm tắt

Hướng dẫn này minh hoạ cách thêm các tiêu đề tuỳ ý vào yêu cầu CORS của thẻ tuỳ chỉnh. Bạn có thể đính kèm các tiêu đề được phê duyệt vào mọi yêu cầu CORS của thẻ tuỳ chỉnh. Các tiêu đề không nằm trong danh sách phê duyệt thường được coi là không an toàn trong các yêu cầu CORS và Chrome sẽ lọc các tiêu đề này theo mặc định. Bạn chỉ được phép đính kèm các tệp này cho những ứng dụng và máy chủ có cùng nguồn gốc, được xác minh bằng một đường liên kết đến tài sản kỹ thuật số.