12/08/2018, 13:49

Lưu nhớ thông tin đăng nhập với Credential Management API

Để cung cấp những trải nghiệm tích cực hơn, một điều quan trọng đó là giúp người sử dụng chủ động xác thực đối với website. Kể từ phiên bản 51 của Chrome đã cung cấp Credential Management API (gọi nôm na là API cung cấp khả năng quản lý chứng chỉ chứng thực), cung cấp cho các nhà phát triển truy ...

Để cung cấp những trải nghiệm tích cực hơn, một điều quan trọng đó là giúp người sử dụng chủ động xác thực đối với website. Kể từ phiên bản 51 của Chrome đã cung cấp Credential Management API (gọi nôm na là API cung cấp khả năng quản lý chứng chỉ chứng thực), cung cấp cho các nhà phát triển truy cập chương trình để quản lý chứng chỉ của trình duyệt và giúp người dùng đăng nhập dễ dàng hơn.

Để hiểu hơn cách Credential Management API hoạt động, bạn hãy dành ra 1 phút để xem video dưới đây nhé. Nhưng trước tiên hãy lưu ý

  • Credential Management API chỉ cung cấp cho Chrome version 51 trở lên nhé. Mình có code 1 đoạn dưới các bạn có thể tham khảo
        var userAgent = window.navigator.userAgent;
		var agentData = userAgent.split('Chrome/')[1];

		if (typeof agentData != 'undefined') {
			agentData = agentData.split(' ')[0];
			chromeVersion = agentData.split('.')[0];
			if (chromeVersion >= 51) {
                // Hàm useCredentialsManagement định nghĩa việc lưu/lấy sử dụng credential
				useCredentialsManagement();
			}
		}
  • Việc sử dụng Credential Management API không giống như cách mà bạn lưu session, cookie nên vui lòng đừng nhầm lẫn với các khái niệm "Ghi nhớ đăng nhập" hay "Đăng nhập tự động" đó của chúng.

1. Credential Management API là gì?

Credential Management API cho phép các nhà phát triển lưu và lấy các password credential(gọi nôm na là chứng chỉ mật khẩu) và federated credential(chứng chỉ liên kết) (2 loại chứng chỉ được đã được định nghĩa). Và nó cung cấp 3 phương thức

navigator.credentials.get() // Lấy thông tin các chứng chỉ tồn tại
navigator.credentials.store() // Lưu chứng chỉ
navigator.credentials.requireUserMediation() // Hủy bỏ auto login

Bằng việc sử dụng những API đơn giản đó, nhà phát triển có thể

  • Cho phép người dùng có thể dăng nhập chỉ bằng một click.
  • Ghi nhớ các tài khoản liên kết mà người dùng đã từng sử dụng để đăng nhập.
  • Đăng nhập lại khi phiên dăng nhập hết hại.

Các chứng chỉ sẽ được lưu lại trong bộ Password Manager của Chrome. Nếu người dùng đã đăng nhập vào Chrome, họ có thể đồng bộ những mật khẩu của người dùng trên nhiêu thiết bị đồng thời. Những mật khẩu được đồng bộ hóa cũng có thể được chia sẻ với các ứng dụng Android đã tích hợp các Khóa thông minh (Smart Lock) cho Passwords API cho Android để có một trải nghiệm đa nền tảng.

2. Tích hợp Credential Management API vào Website của bạn

Cách mà bạn sử dụng Credential Management API với website của bạn có thể rất phụ thuộc và kiến trúc của nó. Ví dụ như là web của bạn có phải single-page hay không? Có phải là nút sign-in đặt ở mọi page không hay chỉ ở top page? Ta không thể cover tất cả những trường hợp đó, nhưng chúng ta hãy có một cái nhìn tại một ứng dụng single-page điển hình.

image02.png

Ta sẽ xem cách lưu một credential như thế nào nhé Giả sử bạn có 1 form HTML như thế này trong trang web của bạn

<form id="form" method="post">
  <input type="text" name="username"/>
  <input type="password" name="password" />
</form>

Vậy thì đoạn jQuery dưới đây sẽ chỉ cho bạn cách để lưu thông tin username-password vào credential nhé. Loại này là Password Credential.

// Khi nhấn nút submit, trước khi submit ta sẽ thực hiện lưu chứng chỉ
// bạn có thể thực hiện theo 1 cách khác tùy ý bạn
$("#login-form").submit(function () {
    // Tạo một Password Credential từ các thông tin của form.
	var cred = new PasswordCredential({
		id: $("#username").val(),
		password: $("#password").val(),
        // Link URL tới icon mà bạn muốn sử dụng (không bắt buộc)
		iconURL: "http://dkfuy30sometm.cloudfront.net/wp-content/uploads/2015/12/mediado.jpg"
	});
    // Lưu lại credential vừa mới tạo bên trên
	navigator.credentials.store(cred);
});

Như vậy, sau này khi bạn get thông tin từ credential nào đó, bạn sẽ có các thông tin như id (mà bạn sử dụng để lưu username), password ( cái này bạn không lấy trực tiếp đựoc đâu nhé, mình sẽ nói thêm ở phần sau) và icon url. Đó là với Password Credential. Vậy với Federated Credential thì sao nhỉ? Thật ra cũng tuơng tự thôi, thay vì việc lưu username password, đối với Federated Credential bạn cần lưu ID và token

    // Tạo một FederatedCredential
	var cred = new FederatedCredential({
		id: uid,
        name: name
		password: token,
        provider: 'https://accounts.google.com' // Xác định nhà cung cấp
		iconURL: iconUrl
	});
    // Lưu lại credential vừa mới tạo bên trên
	navigator.credentials.store(cred);

Vậy là bạn mới được thấy cách mà chúng ta lưu lại chứng chỉ để sử dụng cho việc đăng nhập. Tiếp theo hãy xem cách mà chúng ta sử dụng nó như thế nào nhé.

// Sử dụng navigator.credentials.get
// Trình duyệt Chrome sẽ bắn ra 1 dialog cho phép bạn chọn chứng chỉ đăng nhập nào
// Hãy xem video phía trên để hiểu rõ hơn nhé
navigator.credentials.get({
			password: true, // Chỉ ra rằng có lấy loại PasswordCredential không
			federated: {   // Chỉ ra bằng ta muốn lấy cả FederatedCredential
				// Khai báo những FederatedCredential thuộc nhà cung cấp nào (provider nào) được lấy ra
			    providers: [
			      'https://accounts.google.com',
			      'https://www.facebook.com'
			    ]
			},
			unmediated: false
		}).then(function (cred) {
            // Và khi bạn chọn 1 chứng chỉ nào đó
			if (cred) {
                // Modify idName và passwordName sao cho phù hợp với hệ thống backend của bạn
                // Ví dụ backend nhận giá trị của id cho username, password cho password
				cred.idName = "username";
				cred.passwordName = "password";
                // Sử dụng hàm fetch với phương thức POST gửi credentials lên phía server để thực hiện việc sử lý
				fetch("/login", {credentials: cred, method: "POST"}).then(function (response) {
					console.log(response);
					if (response.status == 200) {
                        // Giờ thì bạn hãy làm gì đó với response trả về nhé.
                        // Ở đây mình chuyển tới trang cá nhân
						window.location.replace("/user/me");
					} else {
						console.log("------ERROR--------");
						// TODO something here later
					}
				});
			} else {
				// nếu không cái nào được chọn
			}
		});

Đừng cố gắng log password của credential bằng javascript vì bạn không thể làm điều đó đâu nhé. Khi thực hiện fetch("/login", {credentials: cred, method: "POST"}) nó sẽ gửi lên cho bạn. Giờ thì hãy xem phía server của mình làm j nhé

    @RequestMapping(value = "login", method = {RequestMethod.POST})
	public @ResponseBody void login(HttpServletRequest request, HttpServletResponse response,
			@RequestParam(name="username") String username, @RequestParam(name="password") String password) {
		String status = SecurityUtil.loginUser(request, userAuthenticationManager, loginHistoryService, username, password);
		response.setStatus(Integer.valueOf(status));
	}

Phía trên mình đã chỉ định gán giá trị của param có key là username cho biến username và password cho password. Nếu ở phía trên bạn không thực hiện

cred.idName = "username";
cred.passwordName = "password";

trước khi sử dụng fetch để gửi data lên server thì lúc này bạn cần phải nhận param là id và password (mặc định)

Như vậy, việc xác thực thế nào là do phía backend bạn xử lý.

Vây là bạn đã biết các làm sao để lưu nhớ thông tin đăng nhập và sử dụng thông tin đó để đăng nhập với các thiết bị khác nhau mà bạn sử dụng tài khoảng Google để dồng bộ chúng rồi nhé.

Hi vọng bài viết này sẽ giúp ích các bạn.

Vui lòng tham khảo thêm tại https://w3c.github.io/webappsec-credential-management/

0