Thứ Năm, 5 tháng 1, 2017

[Series] Hướng dẫn sử dụng ASP.NET Identity (phần 2)

Sau bài 1 của series hướng dẫn sử dụng ASP.NET Identity chắc các bạn cũng đã có cái nhìn tổng quát hơn về công nghệ này rồi nhỉ ^_^. Hôm nay mình sẽ hướng dẫn các bạn sử dụng thêm 1 số chức năng rất quan trọng mà ASP.NET Identity hỗ trợ. Mình sẽ tiếp tục sử dụng project ở phần 1 để thực hành nhé cả nhà. 


Nội dung chính


1. Khóa (Lock) user


Ở một số website khi các bạn truy cập vào trang Login của họ và nhập sai mật khẩu quá nhiều lần thì sẽ hiển thị thông báo rằng tài khoản của bạn tạm thời bị khóa. Đây chính là chức năng mà chúng ta sẽ tìm hiểu đến ở phần mở đầu của bài viết hôm nay.

Đầu tiên để bật chức năng này thì các bạn vào action method Login có attribute [HttpPost] trong AccountController, sau đó thay giá trị của đối số shouldLockout thành true như hình dưới:


Sau đó chúng ta cùng xem đoạn code cấu hình lock user được tìm thấy ở dòng 86 trong file App_Start/IdentityConfig.cs. Hình bên dưới thể hiện đoạn code này:


Mình giải thích ý nghĩa 3 thuộc tính sau:
  • UserLockoutEnabledByDefault: cho phép bật chức năng khóa user
  • DefaultAccountLockoutTimeSpan: thời gian user bị khóa
  • MaxFailedAccessAttemptsBeforeLockout: số lần đăng nhập thất bại tối đa trước khi bị khóa

Như vậy là nếu user nhập sai tài khoản hoặc mật khẩu từ 5 lần trở lên thì user đó sẽ bị khóa 5 phút và sau 5 phút phút bị khóa user đó mới có thể nhập tiếp. Các bạn có thể tùy chỉnh số lần nhập sai tối đa và số phút bị khóa theo ý các bạn nhé 😊.

Ok thử build lại project và test xem nào, bây giờ mình sẽ thử nhập sai mật khẩu của user nguyenaituan@yahoo.com (user mà mình đã đăng ký ở phần 1) 5 lần thì mình sẽ nhận được thông báo sau:

View thể hiện thông báo lỗi được tìm thấy tại file Lockout.cshtml trong folder Views/Shared. Các bạn có thể thiết kế lại view này sao cho nó thân thiện với khách hàng. Mình thiết kế lại view này như hình dưới 😋.



2. Đổi mật khẩu


Một chức năng rất quan trọng là đổi mật khẩu. Mặc định thì ASP.NET Identity đã enable chức năng này nên bây giờ chúng ta thử đổi mật khẩu luôn xem sao nhé, sau đây là các bước để đổi mật khẩu:

Bước 1: Login vào website và click vào link Hello emailcuaban. Trang Manage sẽ hiện ra, đây là trang cá nhân của user đó các bạn.

Bước 2: Click vào link Change your password để vào trang Change Password.

Bước 3: Nội dung trang Change Password hiện ra, bây giờ thì các bạn tiến hành nhập mật khẩu hiện tại, mật khẩu mới, xác thực mật khẩu mới. Các bạn nhớ quy tắc về mật khẩu chúng ta đã thiết lập ở phần 1 chứ, các bạn phải nhập mật khẩu mới theo đúng quy tắc như vậy nhé.

Bước 4: Ấn nút Change Password để chấp nhận đổi mật khẩu.

Đó là các bước mà 1 user cần làm để đổi mật khẩu. Bây giờ về phía người lập trình viên thì chúng ta cần hiểu cơ chế hoạt động của chức năng này.

Đầu tiên khi các bạn click vào link Change your password thì server sẽ gọi đến action ChangePassword trong ManageController (dòng thứ 218). Action này đơn giản chỉ trả về 1 view ChangePassword để hiển thị trang Change Password. Nội dung của view này được tìm thấy tại file ChangePassword.cshtml ở folder Views/Manage.

Nội dung của view Change Password cũng tương tự các view ở phần 1 thôi các bạn nhé. Cũng chỉ có đoạn khai báo model, form và khai báo jqueryval nên mình không giải thích chi tiết nội dung trong view nữa.

Khi user nhấn nút Change Password thì form sẽ được đệ trình và gửi thông tin đến action ChangePassword có attribute [HttpPost] (dòng 227). Nội dung của action này được thể hiện ở hình dưới:



Action này nhận vào 1 tham số đó là đối tượng model chứa các thông tin mà người dùng nhập ở form. Đoạn lệnh đầu tiên trong action kiểm tra xem dữ liệu của form có hợp lệ không, nếu không hợp lệ thì sẽ trả về chính view đó kèm theo model để hiển thị lại trang đi kèm thông báo lỗi. Nếu hợp lệ thì server sẽ thực hiện gọi phương thức ChangePasswordAsync trong class UserManager để thực hiện thay đổi mật khẩu và lưu vào cơ sở dữ liệu. Kết quả sẽ được gán qua biến result. Sau đó lệnh kiểm tra xem việc đổi mật khẩu có thành công không ? Nếu thành công thì thực hiện đăng nhập lại với mật khẩu mới và chuyển hướng về lại trang Manage kèm thông báo đổi mật khẩu thành công.

Vậy là chúng ta đã hiểu về code xử lý change password. Bây giờ đừng quên 1 việc làm nữa đó là cấu hình để hiển thị lỗi tiếng Việt thay vì tiếng Anh ở trang Change Password.

Mở file ManageViewModels.cs trong thư mục Models và tìm đến class ChangePasswordViewModel và sửa thành như sau:



3. Lấy lại mật khẩu


Chức năng này chỉ có thể được sử dụng khi bạn đã cấu hình gửi mail xác nhận khi user đăng ký thành viên bởi vì khi user yêu cầu lấy lại mật khẩu thì ASP.NET Identity sẽ gửi 1 link đến mail của user, khi user đó ấn vào link này thì sẽ trình duyệt sẽ hiện lên trang Reset Password cho user đó thực hiện đặt mật khẩu.

Khác với chức năng đổi mật khẩu thì chức năng lấy lại mật khẩu mặc đinh chưa được enable (bật). Để sử dụng chức năng này thì các bạn mở file Views/Login.cshtml lên và uncomment thẻ <p></p>:

  @* Enable this once you have account confirmation enabled for password reset functionality

                    <p>

                        @Html.ActionLink("Forgot your password?", "ForgotPassword")

                    </p>
*@

Kết quả sau khi uncomment là như thế này:

 //Enable this once you have account confirmation enabled for password reset functionality

                    <p>

                        @Html.ActionLink("Forgot your password?", "ForgotPassword")

                    </p>

Mục tiêu của việc bỏ chú thích thẻ này là để hiển thị link Forgot your password? ở trang Login để khi user click vào thì trình duyệt sẽ chuyển hướng đến trang Forgot password  (quên mật khẩu).


Nội dung của view Forgot Password được tìm thấy tại file ForgotPassword.cshtml trong thư mục Views/Account. Nội dung của view Forgot Password cũng tương tự các view ở phần 1 thôi các bạn nhé. Cũng chỉ có đoạn khai báo model, form và khai báo jqueryval nên mình không giải thích chi tiết nội dung trong view nữa.

Khi user nhập Email và ấn nút Email Link thì form sẽ được đệ trình và gửi thông tin đến action ForgotPassword (dòng thứ 202) có attribute [HttpPost] trong AccountController (xem hình dưới)

Trong action này đầu tiên rất quan trọng là bạn cần uncomment đoạn chú thích từ dòng // string code đến dòng // return RedirectToAction.... để ASP.NET Identity gửi mail chứa link Reset Password đến user.

Mình tiếp tục giải thích. Action này nhận vào 1 tham số là đối tượng model của class ForgotPasswordViewModel. Class này chứa trong file AccountViewModels.cs trong thư mục Models. Các bạn tự cấu hình thông báo lỗi bằng tiếng Việt cho class này nhé.

Lệnh if đầu tiên kiểm tra nếu form hợp lệ thì thực hiện gọi phương thức FindByNameAsync của class UserManager để tìm user theo Email và gán qua biến user.

Lệnh if (user == null || !(await UserManager.IsEmailConfirmedAsync(user.Id))) kiểm tra xem nếu user không tồn tại hoặc có tồn tại nhưng user này chưa xác nhận email (có thể do lúc đăng ký thành viên user này không thực hiện vào mail và xác thực) thì trả ra view ForgotPasswordConfirmation, nội dung của view này các bạn có thể xem tại file ForgotPasswordConfirmation.cshtml trong folder Views/Account. Các bạn hãy sửa lại thành dòng thông báo trong view ForgotPasswordConfirmation cho thân thiện với người dùng nhé. Trong trường hợp form không hợp lệ thì server sẽ trả lại chính view ForgotPassword để hiển thị thông báo lỗi cho người dùng biết.

Các bạn thử trải nghiệm chức năng này nhé.

4. Bổ sung thông tin của user


Mặc định các bạn thấy table dbo.AspNetUsers (table chứa thông tin các user trên web) trong CSDL có sẵn các cột do ASP.NET Identity tự sinh ra. Tuy nhiên bạn muốn bổ sung thêm 1 số thông tin cho user như Họ tên, địa chỉ, giới tính, ... thì làm sao?

Để làm được điều này thì các bạn cần đến kiến thức căn bản về Entity Framework Code First nhé.

Giả sử bây giờ mình muốn bổ sung thêm thông tin họ tên, địa chỉ, giới tính cho các user thì thực hiện như sau:

Bước 1: Tìm đến class ApplicationUser trong file Models/IdentityModels.cs

Bước 2: using namespace System và bổ sung thêm 3 thuộc tính FullName, Address, Gender vào class này như hình dưới




Bước 3: Mở màn hình Package Manage Console lên bằng cách click vào menu Tools -> NuGet Package Manage -> Package Manage Console ở Visual Studio.

Bước 4: Ở màn hình Package Manage Console nhập enable-migrations và nhấn Enter

Bước 5: Nhập add-migration updateUser-1.0 và nhấn Enter.

Bước 6: Gõ update-database và nhấn Enter

Mở CSDL và đảm bảo rằng 3 cột FullName, Address, Gender đã được thêm vào table dbo.AspNetUsers như hình dưới là OK



Như vậy là bạn vừa bổ sung thêm 3 cột vào table AspNetUsers.

Bây giờ chúng ta tiến hành cho người dùng nhập những thông tin này khi đăng ký thành viên.

Bước 1: Tìm đến class RegisterViewModel trong file Models/AccountViewModels.cs và bổ sung các lệnh được tô đen



Bước 2: Mở file Views/Account/Register.cshtml và thêm các lệnh được tô đen



Bước 3: Mở action method Register có attribute [HttpPost] trong AccountController và sửa đoạn lệnh var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; thành var user = new ApplicationUser { UserName = model.Email, Email = model.Email,  FullName = model.FullName, Address = model.Address, Gender = model.Gender  };

Sau khi thực hiện xong tất cả các thao tác trên thì bạn build project và truy cập vào trang Register sẽ thấy giao diện thay đổi như sau:



Tức là kể từ giờ khi user đăng ký thì cần cung cấp thêm họ tên, địa chỉ, giới tính của họ. Vậy là chúng ta đã thêm thông tin user thành công rồi đó.👌

5. Tổng kết


Qua bài viết này chúng ta đã hiểu thêm các chức năng rất hay khác mà ASP.NET Identity hỗ trợ. Tuy nhiên mọi thứ vẫn chưa hết, vẫn còn nhiều thứ hay ho chúng ta chưa khám phá hết. Ở phần 3 chúng ta sẽ tiếp tục tìm hiểu và cài đặt các chức năng sau cho web:

  1. Đăng nhập thông qua tài khoản facebook, google plus, twitter
  2. Set password
  3. Phân quyền user
Nếu thấy bài viết của mình có ích cho bạn hãy like + comment nhiệt tình vào nhé :)). Đừng quên đăng ký để nhận được những bài viết mới nhất từ Blog Chuyên Lập Trình nhé. Hẹn gặp lại các bạn ở bài viết tiếp theo trong series 👍.


EmoticonEmoticon