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:
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:
Vì hàm
fetch()
tuỳ chỉnh không còn bắt buộc để tìm nạp mật khẩu, nên hàm này sẽ sớm ngừng hoạt động.navigator.credentials.get()
hiện chấp nhận enummediation
thay vì cờ booleanunmediated
.Phương thức mới
navigator.credentials.create()
tạo các đối tượng thông tin xác thực một cách không đồng bộ.
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
.
navigator.credentials.get()
hiện chấp nhận tính năng dàn xếp enum
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.