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 được giải thích trong phiên Google I/O, Đăng nhập an toàn và liền mạch: Giữ chân người dùng:

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 xác thực từ một miền con khác

Giờ đây, Chrome 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 Credential Management API (API Trình 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ị mật khẩu đó 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 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 truyền và sao chép vào 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 nguồn gốc www.example.com trở đi.

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

Bộ chọn tài khoản hiển thị thông tin đăng nhập của 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 tính năng phát hiện

Để xem liệu có API Trình quản lý thông tin xác thực để truy cập vào thông tin xác thực liên kết và dựa trên mật khẩu 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

Credential Manager API đã áp dụng phương pháp bảo thủ để xử lý mật khẩu. Phương thức 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 cho API fetch().

Tuy nhiên, phương pháp này cũng có 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 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 mình.

Sau khi phân tích bảo mật và nhận thấy 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 hiệu quả như chúng tôi mong đợi, chúng tôi đã quyết định 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 cho máy chủ:

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 có đang sử dụng hàm fetch() tuỳ chỉnh hay không, hãy kiểm tra xem hàm đó có sử dụng đối tượng PasswordCredential hay đối tượng FederatedCredential làm giá trị của thuộc tính credentials hay không, ví dụ:

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

Bạn nên sử dụng hàm fetch() thông thường như trong ví dụ về mã 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 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ị bộ 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. Việc 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 một cách rõ ràng sau lệnh 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 truyền mà không hiển thị bộ chọn tài khoản.
optional Bằng unmediated: false Hiển thị bộ 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ị bộ 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ị bộ 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 được đổi tên ngăn việc truyền thông tin xác thực mà không hiển thị bộ chọn tài khoản (đôi khi được gọi là không có sự dàn xếp của người dùng). Điều này 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 trong 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ó thể tạo các đố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(). Hãy đọc tiếp để so sánh cả hai phương pháp đồng bộ 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 đã triển khai API Quản lý thông tin xác thực chưa? 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.