[Angular 2 – Meteor]. 5. Xác thực người dùng trong Angular 2 Meteor.

Chào các bạn, hôm nay chúng ta sẽ tiếp tục với Series Angular 2 Meteor, trong bài viết trước về Data Binding chúng ta đã tìm hiểu và nắm được việc tương tác dữ liệu qua lại giữa phần Logic và phần Template trong 1 Component và những khái niệm đó là của Angular, ở phía client. Thì như chúng ta cũng biết là đa số các ứng dụng web bây giờ đều đòi hỏi việc đăng ký, đăng nhập để có thể truy cập và sử dụng ứng dụng.

Từ thông tin mà người dùng cung cấp thì người ta có thể biết được ai là người đã thực hiện những thao tác với ứng dụng. Ví dụ như một trang quản lý của 1 trường đại học, thì với mỗi sinh viên hay giáo viên chúng ta đều cần mỗi người có 1 tài khoản, để dựa vào đó chúng ta biết được người đó dã thao tác gì trong trang web, và cũng dựa vào đó để chúng ta cho phép tài khoản đó xem được những thông tin gì trong trang quản lý, như là sinh viên thì chỉ được xem thời khóa biểu + bảng điểm của cá nhân sinh viên đó, còn giáo viên thì tài khoản sẽ có thể xem được thông tin của tất cả các sinh viên chẳng hạn. Thì đó là việc sinh ra quản lý tài khoản và quyền truy xuất dữ liệu. Và để làm được những điều trên thì chúng ta sẻ đi vào bài viết hôm nay để xem Meteor cung cấp cho chúng ta những gì và chúng ta sẽ thực hiện như thế nào với nó.

Bài viết mình sẽ trình bày về việc xác thực người dùng trong Meteor:

  • Xác thực người dùng: Tìm hiểu về package accounts-password mà Meteor cung cấp và sử dụng chúng trong ứng dụng. Và từ đó sử dụng trong ứng dụng Meteor của chúng ta như là kích hoạt router cho các trang chứa tài nguyên của cá nhân từng user.

Chi tiết hơn chúng ta sẽ đi vào nội dung chi tiết và chúng ta sẽ biết những cái mà chúng ta kể trên là gì, nó hoạt động như thế nào, và cả việc áp dụng nó như thế nào.

Xác thực người dùng:

Tài khoản người dùng (User Accounts)

Như ở trên chúng ta đã đề cập tới một package mà Meteor cung cấp cho chúng ta để quản lý người dùng là package accounts-password, thì package này cung cấp cho chúng ta gần như là đầy đủ các phương thức thao tác với tài khoản như là đăng nhập, đăng ký, quên mật khẩu… Để có thể sử dụng package đó trong ứng dụng thì chúng ta sẽ sử dụng cú pháp cài đặt package của Meteor đó là:

meteor add accounts-password

Với package này thì Meteor cung cấp cho chúng ta các chức năng đăng ký, đăng nhập, quên mật khẩu, để các bạn sử dụng chúng và xây dựng nên hệ thống chứng thực của các bạn. Bên cạnh đó, team phát triển Angular 2 Meteor cũng có một Module đã làm sẵn các chức năng đó, tức là đã có form để các bạn đăng ký đăng nhập các kiểu, các bạn chỉ cần import Module đó vào và sử dụng Directive login-buttons của Module này. Trước khi sử dụng được Module này thì chúng ta cần phải cài cái package của nó trên npm. Câu lệnh:

meteor npm install --save angular2-meteor-accounts-ui

Mặc dù là người ta làm sẵn nhưng mình thấy đa số chúng ta sẽ tự viết lại theo một template khác, và thêm một số thao tác cần thiết khi đăng nhập, đăng ký… thì cái này tùy thuộc vào requirement của từng dự án nên mình không bàn gì thêm. Hoặc thậm chí mình cũng có thể kế thừa từ module ui trên.

Trước khi đưa package trên vào sử dụng thì mình xin nói thêm về 1 package được thêm ngầm ở phía dưới khi thêm package accounts-password có tên là accounts-base. Với các chức năng chính đó là:

  • Tạo 1 Collections users trong database với cấu trúc (schema) chuẩn, thay vì các Collection khác chúng ta sẽ phải tạo 1 biến MongoCollection và đặt tên cho nó, sau đó sẽ sử dụng biến này để truy xuất tới Collection, thì với collection users này Meteor cung cấp cho chúng ta 1 biến Meteor.users để có thể truy xuất vào Collection users. Bên cạnh đó còn có những singletons là Meteor.userId() và Meteor.user() cho phép client lấy id user của mình, hoặc là lấy đối tượng user chứa thông tin cá nhân của user đó.
  • Tiếp theo là các phương thức login, logout để chúng ta có thể thực hiện các tác vụ tương ứng.
  • Cho phép chúng ta bắt sự kiện lúc đăng nhập…, để kiểm tra một số thông tin của tài khoản nhằm xác thực trước khi cho phép đăng nhập để nâng cao tính bảo mật cũng như đảm bảo về một số yêu cầu từ dự án chẳng hạn.

Đó là một số cái mình đề cập thêm để các bạn nắm được, còn khi vào sử dụng thì các bạn chỉ cần dùng nó thôi 😀 :D.. Sẽ có những thứ nảy sinh và mình sẽ cố gắng giải thích từng cái cho các bạn để các bạn dễ nắm được cấu trúc của Meteor hơn. Tiếp theo thì chúng ta sẽ áp dụng User Accounts vào ứng dụng tutorial, cho phép login, logout, register các kiểu sử dụng cái Module UI phía trên.

Áp dụng

Đầu tiên thì chúng ta sẽ cần 1 form đăng nhập và chúng ta sẽ sử dụng package UI ở trên, sau đó thì sẽ có 1 phần được gọi là canActivate của mục Routing với mục đích chỉ active đường dẫn trong router khi thỏa mãn một điều kiện nào đó, trong ví dụ thì chúng ta sẽ đòi hỏi với điều kiện là người dùng phải đăng nhập thì mới có thể xem được trang details, và giờ chúng ta sẽ bắt đầu từng thứ 1.

  • Áp dụng Accounts UI package:

Ở trên chúng ta đã import package angular2-meteor-accounts-ui, bây giờ chúng ta sẽ thêm Component AccountModule vào trong AppModule để có thể sử dụng. File AppModule (client/imports/app/app.module.ts) của chúng ta sẽ có nội dung như sau:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { AccountsModule } from 'angular2-meteor-accounts-ui';

import { AppComponent } from './app.component';
import { routes, ROUTES_PROVIDERS } from './app.routes';
import { PARTIES_DECLARATIONS } from './parties';

@NgModule({
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
RouterModule.forRoot(routes),
AccountsModule
],
declarations: [
AppComponent,
...PARTIES_DECLARATIONS
],
providers: [
...ROUTES_PROVIDERS
],
bootstrap: [
AppComponent
]
})
export class AppModule {}

Và như vậy là trong ứng dụng của chúng ta đã có thể sử dụng AccountsModule để sử dụng các Component trong nó, cụ thể hơn thì Module này cung cấp cho chúng ta một Component login-buttons với chức năng cho phép người dùng đăng nhập, với form xây dựng sẵn, cùng với đó là những thao tác khác như là logout nếu đang đăng nhập, hay là hiển thị tên email của người dùng. Và để sử dụng thì chúng ta sẽ thêm 1 thẻ login-buttons vào trong ứng dụng. Chúng ta sẽ thêm vào trang list các party để chúng ta có thể quản lý người dùng tại trang này, template của PartiesList (client/imports/app/parties/parties-list.component.html) sẽ có nội dung như sau:

<div>
<parties-form style="float: left"></parties-form>
<input type="text" #searchtext placeholder="Search by Location">
<button type="button" (click)="search(searchtext.value)">Search</button>

<login-buttons></login-buttons>
<ul>
<li *ngFor="let party of parties | async">
<a [routerLink]="['/party', party._id]">{{party.name}}</a>{{party.description}}

{{party.location}}

<button (click)="removeParty(party)">X</button></li>
</ul>
</div>

Bây giờ chúng ta khởi động lại ứng dụng và chúng ta sẽ thấy kết quả là 1 button login, khi click vào ta sẽ thấy như hình:

login-form
Form login của package UI login

Như vậy là chúng ta đã hoàn tất việc sử dụng package angular2-meteor-accounts-ui trong ứng dụng để phục vụ cho các chức năng quản lý user cần có và tiếp theo chúng ta sẽ đến với một chức năng cũng khá là quan trọng trong ứng dụng web, đó chính là Router CanActivate với chức năng cấp quyền truy cập tới 1 đường dẫn nào đó (active đường dẫn nếu thoả mãn điều kiện) và trong trường này thì sẽ chỉ active trang detail khi user đã login vào.

  • Router CanActivate:

Với chức năng này thì chúng ta sẽ cho phép người dùng truy cập vào một số View khi logic trong ứng dụng cho phép truy cập, ví dụ như trong trường hợp chúng ta sẽ làm đây là chỉ cho truy cập vào trang PartyDetails khi đã đăng nhập vào hệ thống, và chức năng đăng nhập đã có ở trên, bây giờ chúng ta sẽ thực hiện active cho url của trang PartyDetails khi đã đăng nhập.

Chúng ta sẽ vào file app.routes.ts để hiện thực tính năng này, đầu tiên chúng ta sẽ phải tạo 1 PROVIDER đóng vai trò như một bác bảo vệ trong một công ty, khi 1 người vào công ty thì vẫn vào được bình thường, nhưng với những phòng chỉ dành cho nhân viên thì chỉ những người đeo thẻ nhân viên mới có quyền vào trong những căn phòng đó. Ở đây PROVIDER cũng làm một công việc tương tự, với một người dùng khi sử dụng ứng dụng thì người ta vẫn có thể sử dụng bình thường, còn khi người dùng muốn truy cập vào những trang chi tiết (PartyDetails) thì đòi hỏi người dùng phải là thành viên trong hệ thống thì mới có thể xem được Details của Party. Và cũng ko quá phức tạp, mã nguồn của file app.router.ts sẽ như sau:

import { Route } from '@angular/router';

import { PartiesListComponent } from './parties/parties-list.component';
import { PartyDetailsComponent } from './parties/party-details.component';

export const routes: Route[] = [
{ path: '', component: PartiesListComponent },
{ path: 'party/:partyId', component: PartyDetailsComponent, canActivate: ['canActivateForLoggedIn'] }
];

export const ROUTES_PROVIDERS = [{
provide: 'canActivateForLoggedIn',
useValue: () => !! Meteor.userId()
}];

Trong đoạn code trên chúng ta định nghĩa 1 PROVIDER như mình đã giải thích ở trên, thì cái PROVIDER này là một mảng các object, với mỗi object như là 1 người bảo vệ, thì sẽ có tên của người bảo vệ đó (thuộc tính provide), và chức năng xử lý của người bảo vệ đó (thuộc tính useValue), trong trường hợp trên thì PROVIDER có tên là canctivateForLoggedIn, PROVIDER này thực hiện chức năng kiểm tra đã đăng nhập vào hệ thống của mình hay chưa. Sau đó thêm tên PROVIDER vào trong mảng của thuộc tính canActivate trong router. Tuy nhiên, chỉ như thế thì hệ thống sẽ ko hiểu được cái PROVIDER đó ở đâu ra và dĩ nhiên, chúng ta sẽ phải khai báo cho app.module, đó là lý do chúng ta sử dụng thêm từ khoá export để có thể import và sử dụng ở vị trí khác.

Khá là đơn giản, trước đó chúng ta đã export const routes và import nó vào trong module và sử dụng, bây giờ chúng ta cũng sẽ làm tương tự, chỉ khác là routes chúng ta thêm vào imports, còn PROVIDER? Chúng ta sẽ thêm nó vào providers luôn :D.. Và mã nguồn của file app.module.ts sẽ có nội dung:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { AccountsModule } from 'angular2-meteor-accounts-ui';

import { AppComponent } from './app.component';
import { routes, ROUTES_PROVIDERS } from './app.routes';
import { PARTIES_DECLARATIONS } from './parties';

@NgModule({
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
RouterModule.forRoot(routes),
AccountsModule
],
declarations: [
AppComponent,
...PARTIES_DECLARATIONS
],
providers: [
...ROUTES_PROVIDERS
],
bootstrap: [
AppComponent
]
})
export class AppModule {}

Thêm vào trong mục import, dùng spread syntax để thêm mảng các PROVIDER vào trong list providers. Và như vậy là chúng ta đã hoàn tất việc sử dụng tính năng canActivate của router, bây giờ các bạn có thể tự mình vào trong trang web của ứng dụng và thử truy cập vào các party.. và chúng ta sẽ cùng xem trang details bây giờ sẽ hiển thị như thế nào :D.

list-parties
Router cho trang Detail không được active.

Trường hợp chúng ta truy cập trực tiếp vào URL của trang party detail thì chúng ta sẽ thấy trang trắng như sau:

party-detail
Trang detail không được active

Như vậy là PROVIDER của chúng ta đã hoạt động theo đúng như ý chúng ta muốn, bây giờ các bạn có thể login vào và kiểm tra xem khi login các bạn sẽ thấy gì nhé :D..

Tổng kết

Như vậy trong bài viết này chúng ta đã tìm hiểu về một package trong Meteor, giúp chúng ta có thể dễ dàng quản lý và thao tác với tài khoản của người dùng trong ứng dụng từ phía server. Và áp dụng một UI package cho việc quản lý đăng nhập, đăng ký …, Thêm vào đó là việc sử dụng 1 tính năng có sẵn của Router và kết hợp với hệ thống quản lý người dùng để xây dựng các chứng thực trước khi cho phép người dùng có thể sử dụng các chức năng trong hệ thống của bạn. Khá tiện lợi phải không nào :D, tuy nhiên hiện tại các bài viết từ trước đến giờ đều tập trung vào những tính năng trong Angular mà ít đề cập tới Meteor, lợi ích của việc sử dụng Meteor và cả việc những thứ mà Meteor có thể làm được.

Bài viết tới mình sẽ trình bày về một tính năng của Meteor, giúp cho ứng dụng Meteor được gọi là Real-time, đó là Subscriptions trong Meteor. Với 2 khái niệm là Publish và Subscribe, Meteor cho phép chúng ta có thể trao đổi dữ liệu giữa client và server một cách dễ dàng nhất, an toàn nhất. Chi tiết hơn mình sẽ trình bày trong bài viết kế tiếp Angular 2 – Meteor: Subscription (Publish-Subscribe), thao tác với dữ liệu trong Meteor như thế nào và Meteor làm như thế nào?

Tài liệu tham khảo

[1] Meteor: User and Accounts

[[2] Angular 2 – Meteor: User and Authentication(https://angular-meteor.com/tutorials/socially/angular2/users-and-authentication)%5D

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s