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 đã ra mắt thay đổi quan trọng này đối với Credential Management API.

Thông tin đăng nhập có thể được chia sẻ 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 cách sử dụng Credential Management API. Ví dụ: nếu mật khẩu được lưu trữ trong login.example.com, thì một 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 chuyển và sao chép vào nguồn gốc 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 cùng một 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ị với m.aliexpress.com và người dùng có thể chọn:

Trình chọn tài khoản cho thấy thông tin đăng nhập của miền con đã chọn

Chrome 60

Chrome 60 ra mắt một số thay đổi quan trọng đối với Credential Management API:

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

Để xem Credential Management API có thể 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 window.PasswordCredential hoặc window.FederatedCredential có sẵn hay không.

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

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

Credential Management API đã áp dụng một phương pháp thận trọng để xử lý mật khẩu. API này ẩn 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 của API fetch().

Tuy nhiên, phương pháp này 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 họ.

Sau khi 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ư mong đợi, chúng tôi đã quyết định thực hiện thay đổi.

Credential Management API 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 túy. Bạn có thể sử dụng các phương thức hiện có để cung cấp thông tin thông tin xác thực cho máy chủ của mình:

navigator.credentials.get({
    password: true,
    federated: {
    providers: [ 'https://accounts.google.com' ]
    },
    mediation: 'silent'
}).the>n(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 thuộc tính unmediated không bắt buộc có 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 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 một cách rõ ràng sau lệnh gọi navigator.credentials.requireUseMediation().

Chọn một trong các lựa 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ị Trình chọn tài khoản.
optional Bằng unmediated: false Hiện trình chọn tài khoản nếu trước đó đã gọi preventSilentAccess().
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 hộp thoại Trình chọn tài khoản gốc.

Trong ví dụ này, thông tin xác thực được truyề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&>#39;
}).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 sẽ ngăn việc truyền thông tin xác thực mà không hiển thị Trình chọn tài khoản (đôi khi được gọi là không có sự can thiệp 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ý 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 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 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 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 Credential Manager API? 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.