Thông tin cập nhật mới nhất về API quản lý thông tin xác thực

Một số nội dung cập nhật được mô tả ở đây sẽ được giải thích trong phiên hội thảo Google I/O, Đăng nhập an toàn và liền mạch: Thu hút người dùng tương tác:

Chrome 57

Chrome 57 đã giới thiệu thay đổi quan trọng này đối với API Quản lý thông tin xác thực.

Bạn có thể chia sẻ thông tin đăng nhập từ một miền con khác

Giờ đây, Chrome có thể truy xuất thông tin đăng nhập được lưu trữ trong miền con khác bằng cách sử dụng API Quản lý thông tin xác thực. Ví dụ: nếu một mật khẩu được lưu trữ trong login.example.com, một tập lệnh trên www.example.com có thể hiển thị tập lệnh đó dưới dạng một trong các mục tài khoản trong hộp thoại trình chọn tài khoản.

Bạn phải lưu trữ mật khẩu rõ ràng bằng cách sử dụng navigator.credentials.store(), để khi người dùng chọn thông tin xác thực bằng cách nhấn vào hộp thoại, mật khẩu sẽ được chuyển và sao chép sang nguồn gốc hiện tại.

Sau khi được lưu trữ, mật khẩu này sẽ dùng được dưới dạng thông tin đăng nhập có cùng điểm gốc www.example.com trở đi.

Trong ảnh chụp màn hình dưới đây, thông tin đăng nhập được lưu trữ trong login.aliexpress.com hiển thị với m.aliexpress.com và có sẵn để người dùng chọn:

Trình chọn tài khoản hiển thị thông tin đăng nhập miền con đã chọn

Chrome 60

Chrome 60 giới thiệu một số thay đổi quan trọng đối với API Quản lý thông tin xác thực:

Cần chú ý đến việc phát hiện tính năng

Để xem liệu API Quản lý thông tin xác thực để truy cập vào dựa trên mật khẩu và có thông tin đăng nhập liên kết hay không, hãy kiểm tra xem window.PasswordCredential hoặc Bạn có thể dùng window.FederatedCredential.

if (window.PasswordCredential || window.FederatedCredential) {
  // The Credential Management API is available
}

Đối tượng PasswordCredential hiện có chứa mật khẩu

API Quản lý thông tin xác thực áp dụng phương pháp xử lý mật khẩu thận trọng. Công cụ này che giấu mật khẩu khỏi JavaScript, đòi hỏi nhà phát triển để gửi trực tiếp đối tượng PasswordCredential đến máy chủ của họ để xác thực thông qua một tiện ích cho API fetch().

Tuy nhiên, phương pháp này đã đặt ra một số hạn chế. Chúng tôi nhận được ý kiến phản hồi cho biết nhà phát triển không sử dụng được API này vì:

  • Họ phải gửi mật khẩu dưới dạng một phần của đối tượng JSON.

  • Họ phải gửi giá trị băm của mật khẩu đến máy chủ của họ.

Sau khi phân tích tính bảo mật và nhận ra rằng việc che giấu mật khẩu của JavaScript không ngăn chặn được mọi vectơ tấn công hiệu quả như chúng ta mong đợi, chúng tôi đã quyết định thực hiện thay đổi.

API Quản lý thông tin xác thực hiện bao gồm mật khẩu thô trong đối tượng thông tin xác thực được trả về để bạn có quyền truy cập vào đối tượng đó dưới dạng văn bản thuần tuý. Bạn có thể sử dụng các phương thức hiện có để cung cấp thông tin xác thực đến máy chủ của mình:

navigator.credentials.get({
    password: true,
    federated: {
    providers: [ 'https://accounts.google.com' ]
    },
    mediation: 'silent'
}).then(passwordCred => {
    if (passwordCred) {
    let form = new FormData();
    form.append('email', passwordCred.id);
    form.append('password', passwordCred.password);
    form.append('csrf_token', csrf_token);
    return fetch('/signin', {
        method: 'POST',
        credentials: 'include',
        body: form
    });
    } else {

    // Fallback to sign-in form
    }
}).then(res => {
    if (res.status === 200) {
    return res.json();
    } else {
    throw 'Auth failed';
    }
}).then(profile => {
    console.log('Auth succeeded', profile);
});

Tìm nạp tuỳ chỉnh sắp ngừng hoạt động

Cách xác định xem bạn có đang sử dụng hàm fetch() tuỳ chỉnh hay không, kiểm tra xem nó sử dụng đối tượng PasswordCredential hay đối tượng FederatedCredential làm giá trị của thuộc tính credentials, ví dụ:

fetch('/signin', {
    method: 'POST',
    credentials: c
})

Sử dụng hàm fetch() thông thường như trong mã ví dụ trước, hoặc sử dụng XMLHttpRequest.

Cho đến Chrome 60, navigator.credentials.get() đã chấp nhận một thuộc tính unmediated (không bắt buộc) bằng một cờ boolean. Ví dụ:

navigator.credentials.get({
    password: true,
    federated: {
    providers: [ 'https://accounts.google.com' ]
    },
    unmediated: true
}).then(c => {

    // Sign-in
});

Việc đặt unmediated: true sẽ ngăn trình duyệt hiển thị trình chọn tài khoản khi truyền thông tin xác thực.

Cờ này hiện được mở rộng dưới dạng tính năng dàn xếp. Quá trình dàn xếp người dùng có thể diễn ra khi:

  • Người dùng cần chọn một tài khoản để đăng nhập.

  • Người dùng muốn đăng nhập một cách rõ ràng sau cuộc gọi navigator.credentials.requireUseMediation().

Chọn một trong các tuỳ chọn sau cho giá trị mediation:

Giá trị mediation So với cờ boolean Hành vi
silent Bằng unmediated: true Thông tin xác thực đã được chuyển mà không hiển thị trình chọn tài khoản.
optional Bằng unmediated: false Hiển thị trình chọn tài khoản nếu preventSilentAccess() đã được gọi trước đó.
required Một lựa chọn mới Luôn hiển thị trình chọn tài khoản. Hữu ích khi bạn muốn cho phép người dùng chuyển đổi tài khoản bằng cách sử dụng hộp thoại trình chọn tài khoản gốc.

Trong ví dụ này, thông tin đăng nhập được chuyển mà không hiển thị trình chọn tài khoản, tương đương với cờ trước, unmediated: true:

navigator.credentials.get({
    password: true,
    federated: {
    providers: [ 'https://accounts.google.com' ]
    },
    mediation: 'silent'
}).then(c => {

    // Sign-in
});

Đổi tên requireUserMediation() thành preventSilentAccess().

Để điều chỉnh cho phù hợp với thuộc tính mediation mới được cung cấp trong lệnh gọi get(), phương thức navigator.credentials.requireUserMediation() đã được đổi tên thành navigator.credentials.preventSilentAccess().

Phương thức đã đổi tên ngăn việc truyền thông tin đăng nhập mà không hiển thị trình chọn tài khoản (đôi khi được gọi mà không có sự hoà giải của người dùng). Điều này rất hữu ích khi người dùng đăng xuất khỏi một trang web hoặc huỷ đăng ký từ một tài khoản và không muốn tự động đăng nhập lại vào lần truy cập tiếp theo.

signoutUser();
if (navigator.credentials) {
    navigator.credentials.preventSilentAccess();
}

Tạo đối tượng thông tin xác thực không đồng bộ bằng phương thức mới navigator.credentials.create()

Giờ đây, bạn có lựa chọn tạo đối tượng thông tin xác thực một cách không đồng bộ bằng phương thức mới là navigator.credentials.create(). Đọc tiếp để so sánh giữa cả phương pháp đồng bộ hoá và không đồng bộ.

Tạo đối tượng PasswordCredential

Phương pháp đồng bộ hoá
let c = new PasswordCredential(form);
Phương pháp không đồng bộ (mới)
let c = await navigator.credentials.create({
    password: form
});

hoặc:

let c = await navigator.credentials.create({
    password: {
    id: id,
    password: password
    }
});

Tạo đối tượng FederatedCredential

Phương pháp đồng bộ hoá
let c = new FederatedCredential({
    id:       'agektmr',
    name:     'Eiji Kitamura',
    provider: 'https://accounts.google.com',
    iconURL:  'https://*****'
});
Phương pháp không đồng bộ (mới)
let c = await navigator.credentials.create({
    federated: {
    id:       'agektmr',
    name:     'Eiji Kitamura',
    provider: 'https://accounts.google.com',
    iconURL:  'https://*****'
    }
});

Hướng dẫn di chuyển

Bạn hiện đã triển khai API Quản lý thông tin xác thực? Chúng tôi có tài liệu hướng dẫn di chuyển mà bạn có thể làm theo để nâng cấp lên phiên bản mới.