Đơn giản hoá quy trình đăng nhập bằng API quản lý thông tin xác thực

Để cung cấp một trải nghiệm người dùng tinh vi, điều quan trọng là giúp người dùng xác thực bản thân họ với trang web của bạn. Người dùng được xác thực có thể tương tác với nhau bằng hồ sơ chuyên dụng, đồng bộ hoá dữ liệu giữa các thiết bị hoặc xử lý dữ liệu khi không có mạng; danh sách cứ tiếp tục lặp lại. Tuy nhiên, việc tạo, ghi nhớ và nhập mật khẩu có xu hướng cồng kềnh đối với người dùng cuối, đặc biệt là trên màn hình thiết bị di động, dẫn đến việc họ sử dụng lại cùng một mật khẩu trên nhiều trang web. Tất nhiên, đây là một rủi ro bảo mật.

Phiên bản mới nhất của Chrome (51) hỗ trợ API Quản lý thông tin xác thực. Đây là một đề xuất theo dõi tiêu chuẩn tại W3C, cho phép nhà phát triển truy cập theo phương thức lập trình vào trình quản lý thông tin xác thực của trình duyệt và giúp người dùng đăng nhập dễ dàng hơn.

API Quản lý thông tin xác thực là gì?

API Quản lý thông tin xác thực cho phép nhà phát triển lưu trữ và truy xuất thông tin xác thực mật khẩu cũng như thông tin xác thực được liên kết, đồng thời API này cung cấp 3 chức năng:

  • navigator.credentials.get()
  • navigator.credentials.store()
  • navigator.credentials.requireUserMediation()

Bằng cách sử dụng các API đơn giản này, nhà phát triển có thể làm những việc mạnh mẽ như:

  • Cho phép người dùng đăng nhập chỉ bằng một lần nhấn.
  • Ghi nhớ tài khoản liên kết mà người dùng đã dùng để đăng nhập.
  • Đăng nhập lại cho người dùng khi phiên hết hạn.

Trong quá trình triển khai của Chrome, thông tin đăng nhập sẽ được lưu trữ trong trình quản lý mật khẩu của Chrome. Nếu người dùng đăng nhập vào Chrome, họ có thể đồng bộ hoá mật khẩu của người dùng trên các thiết bị. Bạn cũng có thể chia sẻ các mật khẩu đã đồng bộ hoá đó với các ứng dụng Android đã tích hợp API Smart Lock cho Mật khẩu cho Android để mang lại trải nghiệm liền mạch trên nhiều nền tảng.

Tích hợp API Quản lý thông tin xác thực với trang web của bạn

Cách bạn sử dụng API Quản lý thông tin xác thực với trang web của mình có thể thay đổi tuỳ thuộc vào cấu trúc của trang web. Đó có phải là ứng dụng trang đơn không? Đó có phải là một cấu trúc cũ với các hiệu ứng chuyển đổi trang không? Có phải biểu mẫu đăng nhập chỉ nằm ở trang trên cùng không? Nút đăng nhập có ở mọi nơi không? Người dùng có thể duyệt trang web của bạn một cách có ý nghĩa mà không cần đăng nhập không? Liên kết có hoạt động trong cửa sổ bật lên không? Hay nó có đòi hỏi tương tác trên nhiều trang không?

Gần như không thể đề cập đến tất cả các trường hợp đó, nhưng hãy cùng xem một ứng dụng trang đơn điển hình.

  • Trang trên cùng là một biểu mẫu đăng ký.
  • Khi nhấn vào nút "Đăng nhập", người dùng sẽ được chuyển đến một biểu mẫu đăng nhập.
  • Cả biểu mẫu đăng ký và biểu mẫu đăng nhập đều có các tuỳ chọn thông thường về thông tin xác thực và liên kết mã nhận dạng/mật khẩu, ví dụ: Đăng nhập bằng Google và Đăng nhập bằng Facebook.

Khi sử dụng API Quản lý thông tin xác thực, bạn có thể thêm các tính năng sau vào trang web, ví dụ:

  • Hiện trình chọn tài khoản khi đăng nhập: Hiển thị giao diện người dùng của trình chọn tài khoản gốc khi người dùng nhấn vào "Đăng nhập".
  • Lưu trữ thông tin đăng nhập: Khi đăng nhập thành công, hãy đề nghị lưu trữ thông tin đăng nhập vào trình quản lý mật khẩu của trình duyệt để sử dụng sau.
  • Cho phép người dùng tự động đăng nhập lại: Cho phép người dùng đăng nhập lại nếu phiên đã hết hạn.
  • Tự động đăng nhập vào Mediate: Sau khi người dùng đăng xuất, hãy tắt tính năng tự động đăng nhập cho lần truy cập tiếp theo của người dùng.

Bạn có thể trải nghiệm những tính năng này được triển khai trên một trang web minh hoạ bằng mã mẫu của trang web đó.

Hiển thị Trình chọn tài khoản khi đăng nhập

Từ lúc người dùng nhấn vào nút "Đăng nhập" và chuyển đến biểu mẫu đăng nhập, bạn có thể sử dụng navigator.credentials.get() để lấy thông tin đăng nhập. Chrome sẽ hiển thị giao diện người dùng của trình chọn tài khoản để người dùng có thể chọn tài khoản.

Giao diện người dùng của trình chọn tài khoản sẽ bật lên để người dùng chọn tài khoản cần đăng nhập.
Giao diện người dùng của trình chọn tài khoản sẽ bật lên để người dùng chọn tài khoản cần đăng nhập

Nhận đối tượng thông tin xác thực mật khẩu

Để hiển thị thông tin xác thực mật khẩu dưới dạng các lựa chọn tài khoản, hãy sử dụng password: true.

navigator.credentials.get({
    password: true, // `true` to obtain password credentials
}).then(function(cred) {
    // continuation
    ...

Sử dụng thông tin đăng nhập mật khẩu để đăng nhập

Sau khi người dùng lựa chọn tài khoản, hàm phân giải sẽ nhận được thông tin xác thực mật khẩu. Bạn có thể gửi tệp này đến máy chủ bằng fetch():

    // continued from previous example
}).then(function(cred) {
    if (cred) {
    if (cred.type == 'password') {
        // Construct FormData object
        var form = new FormData();

        // Append CSRF Token
        var csrf_token = document.querySelector('csrf_token').value;
        form.append('csrf_token', csrf_token);

        // You can append additional credential data to `.additionalData`
        cred.additionalData = form;

        // `POST` the credential object as `credentials`.
        // id, password and the additional data will be encoded and
        // sent to the url as the HTTP body.
        fetch(url, {           // Make sure the URL is HTTPS
        method: 'POST',      // Use POST
        credentials: cred    // Add the password credential object
        }).then(function() {
        // continuation
        });
    } else if (cred.type == 'federated') {
        // continuation

Sử dụng thông tin xác thực liên kết để đăng nhập

Để hiển thị các tài khoản được liên kết cho người dùng, hãy thêm federated. Phương thức này sẽ đưa một mảng nhà cung cấp danh tính vào các tuỳ chọn get().

Khi nhiều tài khoản được lưu trữ trong trình quản lý mật khẩu.
Khi nhiều tài khoản được lưu trữ trong trình quản lý mật khẩu
navigator.credentials.get({
    password: true, // `true` to obtain password credentials
    federated: {
    providers: [  // Specify an array of IdP strings
        'https://accounts.google.com',
        'https://www.facebook.com'
    ]
    }
}).then(function(cred) {
    // continuation
    ...

Bạn có thể kiểm tra thuộc tính type của đối tượng thông tin xác thực để xem đó là PasswordCredential (type == 'password') hay FederatedCredential (type == 'federated'). Nếu thông tin xác thực là FederatedCredential, thì bạn có thể gọi API thích hợp bằng thông tin có trong thông tin đó.

    });
} else if (cred.type == 'federated') {
    // `provider` contains the identity provider string
    switch (cred.provider) {
    case 'https://accounts.google.com':
        // Federated login using Google Sign-In
        var auth2 = gapi.auth2.getAuthInstance();

        // In Google Sign-In library, you can specify an account.
        // Attempt to sign in with by using `login_hint`.
        return auth2.signIn({
        login_hint: cred.id || ''
        }).then(function(profile) {
        // continuation
        });
        break;

    case 'https://www.facebook.com':
        // Federated login using Facebook Login
        // continuation
        break;

    default:
        // show form
        break;
    }
}
// if the credential is `undefined`
} else {
// show form
Biểu đồ quy trình quản lý thông tin xác thực.

Thông tin đăng nhập lưu trữ

Khi người dùng đăng nhập vào trang web của bạn bằng một biểu mẫu, bạn có thể sử dụng navigator.credentials.store() để lưu trữ thông tin đăng nhập. Người dùng sẽ được nhắc có lưu trữ hay không. Tuỳ thuộc vào loại thông tin xác thực, hãy sử dụng new PasswordCredential() hoặc new FederatedCredential() để tạo đối tượng thông tin xác thực mà bạn muốn lưu trữ.

Chrome sẽ hỏi người dùng xem họ có muốn lưu trữ thông tin đăng nhập (hoặc nhà cung cấp liên kết) không.
Chrome sẽ hỏi người dùng xem họ có muốn lưu trữ thông tin đăng nhập (hoặc nhà cung cấp liên kết)

Tạo và lưu trữ thông tin xác thực mật khẩu từ phần tử biểu mẫu

Mã sau đây sử dụng các thuộc tính autocomplete để tự động ánh xạ các phần tử của biểu mẫu với tham số đối tượng PasswordCredential.

html <form id="form" method="post"> <input type="text" name="id" autocomplete="username" /> <input type="password" name="password" autocomplete="current-password" /> <input type="hidden" name="csrf_token" value="******" /> </form> HTML

JavaScript

var form = document.querySelector('\#form');
var cred = new PasswordCredential(form);
// Store it
navigator.credentials.store(cred)
.then(function() {
    // continuation
});

Tạo và lưu trữ thông tin xác thực được liên kết

// After a federation, create a FederatedCredential object using
// information you have obtained
var cred = new FederatedCredential({
    id: id,                                  // The id for the user
    name: name,                              // Optional user name
    provider: 'https://accounts.google.com',  // A string that represents the identity provider
    iconURL: iconUrl                         // Optional user avatar image url
});
// Store it
navigator.credentials.store(cred)
.then(function() {
    // continuation
});
Sơ đồ quy trình đăng nhập.

Cho phép người dùng tự động đăng nhập lại

Khi một người dùng rời khỏi trang web của bạn và quay lại sau đó, thì có thể phiên hoạt động đã hết hạn. Đừng bận tâm người dùng phải nhập mật khẩu của họ mỗi khi họ quay lại. Cho phép người dùng tự động đăng nhập lại.

Khi người dùng được đăng nhập tự động, một thông báo sẽ bật lên.
Khi người dùng được đăng nhập tự động, một thông báo sẽ bật lên.

Lấy đối tượng thông tin xác thực

navigator.credentials.get({
    password: true, // Obtain password credentials or not
    federated: {    // Obtain federation credentials or not
    providers: [  // Specify an array of IdP strings
        'https://accounts.google.com',
        'https://www.facebook.com'
    ]
    },
    unmediated: true // `unmediated: true` lets the user automatically sign in
}).then(function(cred) {
    if (cred) {
    // auto sign-in possible
    ...
    } else {
    // auto sign-in not possible
    ...
    }
});

Mã sẽ giống với mã bạn thấy trong phần "Hiển thị trình chọn tài khoản khi đăng nhập". Điểm khác biệt duy nhất là bạn sẽ đặt unmediated: true.

Việc này sẽ phân giải hàm ngay lập tức và cung cấp cho bạn thông tin đăng nhập để tự động đăng nhập người dùng. Có một số điều kiện sau:

  • Người dùng đã xác nhận tính năng đăng nhập tự động trong lời chào mừng nồng nhiệt.
  • Người dùng trước đây đã đăng nhập vào trang web bằng API Quản lý thông tin xác thực.
  • Người dùng chỉ có một thông tin xác thực được lưu trữ cho nguồn gốc của bạn.
  • Người dùng đã không đăng xuất một cách rõ ràng trong phiên trước đó.

Nếu không đáp ứng bất kỳ điều kiện nào trong số này, hàm sẽ bị từ chối.

Sơ đồ quy trình đối tượng thông tin xác thực

Tự động đăng nhập tại Mediate

Khi người dùng đăng xuất khỏi trang web của bạn, bạn có trách nhiệm đảm bảo rằng người dùng sẽ không tự động đăng nhập lại. Để đảm bảo điều này, API Quản lý thông tin xác thực cung cấp cơ chế có tên là dàn xếp. Bạn có thể bật chế độ dàn xếp bằng cách gọi navigator.credentials.requireUserMediation(). Miễn là bạn bật trạng thái dàn xếp của người dùng cho nguồn gốc bằng cách sử dụng unmediated: true với navigator.credentials.get(), thì hàm đó sẽ phân giải bằng undefined.

Tự động đăng nhập đang dàn xếp

navigator.credentials.requireUserMediation();
Biểu đồ quy trình tự động đăng nhập.

Câu hỏi thường gặp

JavaScript trên trang web có thể truy xuất mật khẩu thô không? Không. Bạn chỉ có thể lấy mật khẩu dưới dạng một phần của PasswordCredential và mật khẩu sẽ không bị lộ dưới bất kỳ hình thức nào.

Tôi có thể lưu trữ 3 bộ chữ số cho một mã nhận dạng bằng API quản lý thông tin xác thực không? Hiện tại thì chưa. Chúng tôi rất trân trọng ý kiến phản hồi của bạn về quy cách.

Tôi có thể sử dụng API Quản lý thông tin xác thực bên trong iframe không? API này chỉ dành cho các ngữ cảnh cấp cao nhất. Các lệnh gọi đến .get() hoặc .store() trong iframe sẽ phân giải ngay lập tức mà không có hiệu lực.

Tôi có thể tích hợp tiện ích quản lý mật khẩu của Chrome với API Quản lý thông tin xác thực không? Bạn có thể ghi đè navigator.credentials và kết nối tiện ích này với Tiện ích của Chrome bằng thông tin đăng nhập get() hoặc store().

Tài nguyên

Để tìm hiểu thêm về API Quản lý thông tin xác thực, hãy xem bài viết Hướng dẫn tích hợp.