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ả sau đây sẽ được giải thích trong phiên Google I/O, Đăng nhập an toàn và liền mạch: Duy trì tương tác của người dùng:

Chrome 57

Chrome 57 đã ra mắt 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

Chrome hiện có thể truy xuất thông tin xác thực được lưu trữ trong một 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 khẩu được lưu trữ trong login.example.com, thì 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 một cách rõ ràng bằng navigator.credentials.store() để khi người dùng chọn một 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 hiện tại.

Sau khi được lưu trữ, mật khẩu sẽ có sẵn dưới dạng thông tin xác thực trong chính www.example.com nguồn gốc trở đi.

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

Trình chọn tài khoản hiển thị chi tiết đăng nhập cho miền con được 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 có API Quản lý thông tin xác thực dùng để truy cập thông tin xác thực dựa trên mật khẩu và liên kết hay không, hãy kiểm tra xem có window.PasswordCredential hoặc window.FederatedCredential hay không.

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

Đối tượng PasswordCredential hiện bao gồm mật khẩu

API quản lý thông tin xác thực đã áp dụng một phương pháp thận trọng trong việc xử lý mật khẩu. Cấu hình này che giấu mật khẩu khỏi JavaScript, yêu cầu 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 đến API fetch().

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

  • Họ phải gửi mật khẩu như 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 thực hiện phân tích bảo mật và nhận thấy rằng việc ẩn mật khẩu khỏi JavaScript không ngăn chặn được tất cả các vectơ tấn công một cách hiệu quả như kỳ vọng, 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 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 mật khẩu đó 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ó để phân phối 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ính năng tìm nạp tuỳ chỉnh sắp ngừng hoạt động

Để xác định xem bạn đang dùng hàm fetch() tuỳ chỉnh hay không, hãy kiểm tra xem hàm đó 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
})

Bạn nên sử dụng hàm fetch() thông thường như minh hoạ trong ví dụ về mã ở trên hoặc bạn nên 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 với 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 chuyển thông tin xác thực.

Cờ hiện được mở rộng dưới dạng dàn xếp. Quá trình dàn xếp người dùng có thể xảy 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 rõ ràng sau khi 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 Đã vượt qua thông tin đăng nhập 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() đã gọi trước đó.
required 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 hộp thoại bộ chọn tài khoản gốc.

Trong ví dụ này, thông tin xác thực đượ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().

Để 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 chuyể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ần người dùng dàn xếp). Đ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ý khỏi một trang web 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 một cách không đồng bộ bằng phương thức mới navigator.credentials.create()

Bạn hiện có thể 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, navigator.credentials.create(). Hãy đọ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 tiếp cận 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 tiếp cận 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? Bạn có thể làm theo tài liệu hướng dẫn di chuyển của chúng tôi để nâng cấp lên phiên bản mới.