AWS Cognito
Mình muốn xây dựng một hệ thống để sử dụng các dịch vụ của Amazone như IoT, DynamoDB, API Getway,… và mình đã gặp phải rất nhiều vấn đề như:
- Xây dựng cơ chế authenticate bảo mật
- Cơ chế confirm authenticate phải chính xác (sms, email,…)
- Có thể authenticate với các Identity Provider khác như facebook, google…
- Có thể phân quyền được cho các user, tổi thiểu là quyền mặc định sau khi authenticate
- Các thiết bị của người dùng phải được đồng bộ dữ liệu sau khi login
- …
AWS cung cấp dịch vụ Cognito để giải quyết các vấn đề trên với 3 dịch vụ cơ bản
- Amazon Cognito Federated Identities
- Amazon Cognito Sync
- Amazon Cognito User Pools
Amazon Cognito Federated Identities
Để đăng nhập vào hệ thống của mình, người dùng chỉ việc đăng nhập vào những trang khác (Identities Provider) như Facebook, Googlde, Twtitter… Hoặc chính Identity Provider của bạn (Bạn có thể tự tạo ra mà)
-
Các bạn có thể tạo nhiều cấu hình (Identity Pool) với các mục đích sử dụng khác nhau. Ví dụ:
- 1 Identity Pool cho admin/manager side
- 1 Identity Pool cho client side
- 1 Identity Pool cho API-Getway-Lambda để xử lý các thao tác tự động
- …
-
Ta có thể tùy chỉnh rất nhiều thứ từ Cognito Ferderate, ví dụ như
- Unauthenticate – người dùng không cần đăng nhập mà chỉ cần sử dụng các API SDK để thao tác với hệ thống với Role được set
- Authenticate – người dùng đăng nhập thông qua các Identity Provider với Role mặc định cho người dùng sau khi họ authenticate vào hệ thống của ta
- …
-
Lưu ý: Các Role, Policy, User, Group… sẽ được cấu hình bên dịch vụ AWS Identity Access Management – AWS IAM
Mỗi một Identity Pool như trên sẽ có 1 Identity Pool ID định danh, và chúng ta sẽ dùng ID này để thao tác trên hệ thống của chúng ta thông qua các SDK API mà aws cung cấp, bên dưới là 1 đoạn code mẫu từ javascript
// Initialize the Amazon Cognito credentials provider AWS.config.region = ‘us-east-1’; // Region AWS.config.credentials = new AWS.CognitoIdentityCredentials({ IdentityPoolId: ‘us-east-1:709c8ba2-62ec-440a-84f7-2c21a4b20628’, });
Vậy sau khi đăng nhập xong, làm sao tôi có thể biết hiện tại đã có bao nhiêu user đăng nhập vào hệ thống của tôi ? Và những user đó là gì? Rồi các thiết bị đăng nhập cùng user có được đồng bộ dữ liệu không ? Dữ liệu lưu trữ sẽ ra sao…v.v…
Tất nhiên sẽ có bạn đưa ra kịch bản như sau để quản lý công việc khó khăn này.
- User đăng nhập hệ thống
- User cập nhật thông tin cá nhân (họ tên, …) hoặc lấy thông tin từ các Identity Provider như Facebook, Google mà mình đã đăng nhập
- Lưu trữ những thông tin trên vào 1 database (DynamoDB chẳng hạn) đã được định sẵn
Hoàn toàn khả thi. Nhưng sẽ gặp một số vấn đề đấy – không nhỏ đâu (mình không tranh luận ở đây). Đây là lúc ta phải cần đến Cognito Synchronize
Amazon Cognito Syn
Sau khi đăng nhập vào hệ thống, Cognito sẽ tạo cho mỗi user 1 Identity ID. Và 1 store nho nhỏ (Các Datasets) để lưu trữ các thông tin cần thiết
Chú ý: Idendity ID này chỉ được tạo khi và chỉ khi người dùng Authenticate thành công. Nếu quản trị viên vào cố tình xóa ID này thì sau khi user đăng nhập lại, Cognito sẽ tự tạo 1 Identity ID mới (khác với ID ban đầu). Vì sao mình phải nhấn mạnh điều này, vì có một số dịch vụ phải cần ID này để thao tác trực tiếp (IoT chẳng hạn – mình sẽ đề cập khi viết về IoT)
Với Identity ID này (Sau khi Authenticate thành công), bạn có thể dùng nó để thao tác đồng bộ dữ liệu (Datasets) trên các thiết bị khác nhau thông qua các API SDK, bạn có thể lưu trữ bất cứ những gì bạn muốn nhưng phải theo quy tắc sau:
- Mọi thứ là json
- Tối đa 20 dataset
- Mỗi dataset tối đa 1Mb
// Initialize the Cognito Sync client AWS.config.credentials.get(function(){ var syncClient = new AWS.CognitoSyncManager(); syncClient.openOrCreateDataset(‘myDataset’, function(err, dataset) { dataset.put(‘myKey’, ‘myValue’, function(err, record){ dataset.synchronize({ onSuccess: function(data, newRecords) { // Your handler code here } }); }); }); });
Tôi lại gặp một vấn đề khác như sau:
- Lỡ một mai các Identity Provider (Facebook,…) họ thay đổi chính sách và không cho tôi sài ké nữa thì sao ?
- Tôi không muốn phải build 1 Identity Provider đâu, vì rất nhiều chi phí! (không chỉ đơn thuần là $)
Đó là lúc bạn sẽ cần đến Amazon Cognito User Pools. Bạn chỉ cần chi $, còn lại mọi thứ hãy để cho AWS lo
Amazon Cognito User Pools
Bạn có thể cấu hình rất nhiều thứ thông qua Amazon Cognito User Pools như:
- Thông tin tài khoản (attribute) như Email, Password, Phone…
- Đăng nhập bằng email/password, username/password hoặc là phone/password
- Polices cho phép bạn cấu hình mật khảu như chiều dài tối thiểu, phải có kí tự đặc biệt…
- Verification cho phép bạn xác thực thông tin người dùng (đăng ký) thông qua Email, SMS (Phone)… với các template có thể customize được… Và còn nhiều thứ khác nữa như tạo nhóm…
- … và còn nhiều thứ khác nữa …
Và với mỗi Uer Pool được tạo ra, AWS sẽ tạo ra 1 Pool ID, các bạn sẽ phải dùng Pool ID này và kết với Identity Pool ID ở bên trên để thao tác với các SDK API, bên dưới là một đoạn javascript nhỏ
/** * Authticate base on username/email and password * * @param user * @param password */ authenticate(user: string, password: string) { const authenticationDetails = new AuthenticationDetails({ Username: user, Password: password, }); const userPool = new CognitoUserPool(poolData = { UserPoolId: environment.userPoolId, // Cognito User Pool ID ClientId: environment.clientId // Cognito User Pool Application Client }); const cognitoUser = new CognitoUser({ Username: user, Pool: userPool }); cognitoUser.authenticateUser(authenticationDetails, { onSuccess: function (sess) { }, onFailure: function (err) { } }) }
Về quan điểm cá nhân thì thật sự Cognito rất tiện và mạnh. Nhưng cho đến thời điểm này thì mình khá bất mãn với Document của họ, thật sự là rất rối và có lẽ mình vẫn còn chưa quen.
Nếu gặp vấn đề gì về việc cấu hình, mình khuyên bạn nên vào trang forum của họ. Mình đã được giải đáp rất nhiều thứ từ đó.
Bạn có thể hình dung mọi thứ bên trên với ảnh bên dưới nhé
- https://github.com/awslabs/aws-cognito-apigw-angular-auth
- http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/index.html