Với hơn 20.000 sao GitHub và rất nhiều tích hợp, đá quý Devise là một trong những loại đá quý phổ biến nhất trong bối cảnh Ruby. Vậy tại sao chúng ta lại gọi nó là một trong những viên ngọc “ẩn” của Ruby? Chà, mặc dù phổ biến nhưng hầu hết các nhà phát triển chỉ mới sơ lược về các khả năng của thư viện.
Trong loạt bài gồm hai phần này, chúng ta sẽ tìm hiểu sâu về Devise.
Trong phần đầu tiên này, chúng ta sẽ tìm hiểu một số kiến thức cơ bản, bao gồm:
- Devise là gì và tại sao bạn nên sử dụng nó ngay từ đầu, bao gồm một số trường hợp không nên sử dụng nó không để sử dụng nó.
- Cách cài đặt Devise và sử dụng nó trong dự án của bạn.
- Cách tùy chỉnh thư viện cho dự án của bạn.
Trong phần hai, chúng ta sẽ xem xét các cách sử dụng nâng cao hơn của Devise, bao gồm:
- OmniAuth và sử dụng Devise cho các ứng dụng chỉ có API.
- Tích hợp Devise với thư viện ủy quyền.
Hãy bắt đầu!
Điều kiện tiên quyết
Trong hướng dẫn này, chúng ta sẽ sử dụng một ứng dụng Ruby on Rails 7 đơn giản bao gồm người dùng và tác vụ. Người dùng có thể đăng ký, đăng nhập và đăng xuất với quyền truy cập vào create , read , update , và delete hành động cho các nhiệm vụ tùy thuộc vào vai trò được giao của họ.
Chúng tôi sẽ sử dụng ứng dụng này để dần dần xây dựng các tính năng phức tạp hơn bao giờ hết và trong quá trình đó sẽ thể hiện các tính năng mạnh mẽ của Devise trong thực tế.
Hãy bắt đầu bằng phần giới thiệu ngắn gọn về Devise.
Giới thiệu Devise cho Ruby
Devise là một thư viện xác thực được xây dựng dựa trên Warden, một khung xác thực dựa trên Rack.
Warden xử lý các phiên của người dùng bằng cách sử dụng chuỗi phiên an toàn để xác minh danh tính của người dùng đã đăng nhập. Nó cũng xử lý những người dùng không đã đăng nhập để đảm bảo họ không thể truy cập các tài nguyên bị hạn chế.
Nhưng vì Warden hoàn toàn dựa trên Rack nên nó không thêm các hành động, chế độ xem, trợ giúp hoặc bất kỳ tùy chọn cấu hình nào khác cần thiết để xây dựng giải pháp xác thực người dùng phù hợp. Mặt khác, Devise thì có.
Một tính năng đáng chú ý khác của Devise là tính mô-đun của nó. Thư viện có khoảng 10 mô-đun cho phép bạn chỉ định chính xác cách bạn muốn xử lý xác thực trong ứng dụng của mình. Bạn không cần phải sử dụng tất cả 10 mô-đun. Thay vào đó, bạn chỉ kích hoạt và sử dụng những gì bạn cần cho ứng dụng của mình. Chúng ta sẽ xem xét các mô-đun này sau, bao gồm Registerable mô-đun, Omniauthable , Trackable , và những thứ khác.
Với ý nghĩ đó, hãy bắt đầu xây dựng ứng dụng Nhiệm vụ và cài đặt Devise.
Bắt đầu:Cài đặt Devise
Tạo ứng dụng Rails 7 mới bằng bundle exec rails new tasks_app . Ngoài ra, bạn chỉ cần lấy mã của ứng dụng mẫu của chúng tôi từ kho lưu trữ.
Đảm bảo bạn đang ở trong thư mục gốc của ứng dụng, sau đó chạy bundle add devise . Điều này sẽ thêm đá quý Devise vào Gemfile của ứng dụng của bạn. Sau đó, chạy bundle exec rails g devise:install để cài đặt Devise và tạo tệp khởi tạo của nó (chúng ta sẽ xem xét kỹ hơn tệp này khi xem qua các mô-đun của Devise).
Khi bạn chạy lệnh này, trình tạo cũng sẽ cung cấp cho bạn một số gợi ý thiết lập để Devise hoạt động như mong đợi. Chỉ cần làm theo hướng dẫn là bạn có thể bắt đầu.
Tiếp theo, hãy tạo mô hình người dùng mà Devise sẽ làm việc cùng.
Tạo mô hình người dùng Devise
Devise cần một mô hình người dùng. Việc bạn gọi mô hình này là gì hoàn toàn phụ thuộc vào sở thích và trường hợp sử dụng ứng dụng của bạn, nhưng thường là User hoặc Admin .
Hãy tiếp tục và tạo mô hình người dùng Devise với bundle exec rails g devise User . Điều này sẽ tạo ra một User mô hình theo app/models/user.rb , tệp di chuyển để tạo bảng người dùng và lộ trình truy cập tài nguyên người dùng:
Chạy bundle exec rails db:migrate để chạy quá trình di chuyển và thiết lập bảng người dùng. Khi đã xong, giờ đây chúng tôi có một mô hình người dùng mà chúng tôi có thể sử dụng để xác thực mọi thứ.
Tiếp theo, hãy thiết lập mô hình Nhiệm vụ để sử dụng trong tương lai.
Tạo mô hình nhiệm vụ
Hãy nhớ rằng khi sử dụng Devise, ứng dụng đơn giản của chúng ta cần:
- Cho phép người dùng đăng ký.
- Cho phép người dùng đăng nhập và đăng xuất khỏi ứng dụng.
- Cho phép người dùng tạo Tác vụ thuộc về họ.
- Cho phép (hoặc không cho phép) người dùng tương tác với Nhiệm vụ, tùy thuộc vào vai trò của họ.
Với ý nghĩ đó, bây giờ chúng ta hãy tạo mô hình Nhiệm vụ mà người dùng sẽ tương tác:
Bây giờ chúng ta sẽ có một mô hình Nhiệm vụ được liên kết với người dùng đã tạo ra nó, tiêu đề, nội dung và trạng thái (cho biết nó đã được hoàn thành hay chưa).
Sau đó, chạy bundle exec rails db:migrate để tạo bảng nhiệm vụ. Đồng thời đảm bảo rằng bạn liên kết Nhiệm vụ với Người dùng:
Khi bạn chạy trình tạo giàn giáo, mối quan hệ belongs_to :users sẽ tự động được thêm vào mô hình Nhiệm vụ. Tương tự, hãy chỉnh sửa mô hình Nhiệm vụ để sử dụng enum cho trạng thái như hiển thị bên dưới:
Cùng với đó, chúng ta đã sẵn sàng tìm hiểu sâu hơn về Devise. Hãy bắt đầu với phần tổng quan ngắn gọn về các mô-đun của Devise.
Các mô-đun trong Devise cho Ruby
Như chúng tôi đã đề cập trong phần giới thiệu, một trong những tính năng chính của Devise là tính mô-đun của nó. Nhưng "tính mô-đun" thực sự có nghĩa là gì trong trường hợp này? Nó đơn giản có nghĩa là tách quá trình xác thực thành các phần khác nhau để quản lý độc lập.
Phiên bản mới nhất của Devise (tại thời điểm viết bài) chứa 10 mô-đun:
- Cơ sở dữ liệu có thể xác thực được - Mô-đun này sẽ lấy mật khẩu do người dùng cung cấp và chuyển đổi nó thành hàm băm an toàn, sau đó được lưu trữ trong cơ sở dữ liệu. Mô-đun này cũng xử lý việc xác minh khi người dùng đăng nhập.
- Có thể xác thực được - Bật xác thực OmniAuth.
- Có thể khóa - Module này sẽ khóa một tài khoản tùy theo số lần đăng nhập thất bại. Tài khoản có thể truy cập lại được sau một khoảng thời gian nhất định hoặc qua email.
- Có thể theo dõi - Theo dõi số lần đăng nhập mà tài khoản đã thực hiện, địa chỉ IP được sử dụng và dấu thời gian đăng nhập.
- Có thể xác nhận - Gửi email kèm hướng dẫn xác nhận khi đăng ký tài khoản và cũng sẽ kiểm tra xem tài khoản của người dùng có được xác nhận khi họ đăng nhập hay không.
- Có thể đăng ký - Cho phép người dùng đăng ký tài khoản trên ứng dụng của bạn và xử lý việc chỉnh sửa và hủy tài khoản.
- Có thể phục hồi được - Xử lý việc đặt lại mật khẩu và khôi phục tài khoản.
- Có thể hết thời gian chờ - Phiên của người dùng hết hạn sau một khoảng thời gian nhất định.
- Có thể xác thực - Điều này cho phép bạn xác định các quy tắc xác thực tùy chỉnh cho email và mật khẩu do người dùng cung cấp trong quá trình tạo tài khoản.
- Dễ nhớ - Sử dụng cookie để ghi nhớ người dùng trong quá trình xác thực.
Để biết thêm thông tin, tài liệu của Devise về các mô-đun sẽ phục vụ tốt cho bạn. Hiện tại, chúng ta sẽ chuyển sang phần Devise trợ giúp và bộ lọc.
Phát minh ra Trình trợ giúp và Bộ lọc
Một trong những lý do nên sử dụng thư viện xác thực như Devise là để quản lý quyền truy cập vào tài nguyên bộ điều khiển và các chế độ xem liên quan. Devise đi kèm với một bộ công cụ trợ giúp tiện lợi, bao gồm:
user_signed_in?- Kiểm tra xem có người dùng hiện đang đăng nhập hay không.current_user- Cho phép bạn tham khảo người dùng hiện đang đăng nhập. Ví dụ:bạn có thể sử dụng đoạn mã nhưcurrent_user.emailđể lấy email của người dùng hiện đang đăng nhập.user_session- Dành cho phiên của người dùng hiện đang đăng nhập.destroy_user_session_path- Phá hủy phiên của người dùng đã đăng nhập và chuyển hướng đến một đường dẫn được chỉ định hoặc đường dẫn gốc.new_user_session_path- Phản hồi bằng chế độ xem đăng nhập của người dùng.edit_user_registration_path- Cung cấp cho người dùng hiện đang đăng nhập quyền truy cập vào chế độ xem để chỉnh sửa chi tiết đăng ký của họ.new_user_registration_path- Phản hồi với chế độ xem có biểu mẫu đăng ký để đăng ký người dùng mới.
Đó là chuyện của những người giúp việc. Để quản lý quyền truy cập của bộ điều khiển, Devise cung cấp cho bạn một before_action tiện lợi bộ lọc bạn có thể sử dụng như thế này:
Cùng với đó, bây giờ chúng ta hãy chuyển trọng tâm sang cách Devise tích hợp với các tham số mạnh của Rails.
Phát minh và tham số mạnh của Ruby on Rails
Tham số mạnh là một tính năng nổi tiếng của Ruby on Rails giúp ngăn chặn việc gán hàng loạt tham số yêu cầu cho các đối tượng. Các tham số mạnh yêu cầu các tham số yêu cầu phải được khai báo rõ ràng trước khi thực hiện bất kỳ phép gán nào, thường là ở cấp bộ điều khiển.
Devise cũng phản ánh chức năng này bằng cách yêu cầu các tham số phải được xác định rõ ràng trong các hành động thích hợp của bộ điều khiển dành riêng cho Devise:
sign_up- Theo mặc định, điều này được tìm thấy trong bộ điều khiển DeviseDevise::RegistrationsController#create. Các khóa được phép theo mặc định làemail,password, vàpassword_confirmation.sign_in- Điều này được tìm thấy trong bộ điều khiểnDevise::SessionsController#new, với các khóa xác thực được phép mặc địnhemailvàpassword.account_update- Tìm thấy ởDevise::Registrations#update— khóa xác thựcemail,current_password,password, vàpassword_confirmationđược cho phép.
Cách thuận tiện nhất để thêm khóa xác thực của riêng bạn là sử dụng before_action lọc trong ApplicationController , giống như ở đây, nơi chúng tôi thêm username khóa được yêu cầu khi người dùng đăng ký:
Một trường hợp sử dụng thú vị đối với các tham số mạnh của Devise là khi bạn cần chuyển một mảng khóa cho trình khử trùng Devise. Ví dụ:giả sử chúng tôi có một ứng dụng thị trường dành cho người làm việc tự do, trong đó người dùng có thể là "nhà thầu" cho thuê hoặc "người sử dụng lao động" có thể thuê các nhà thầu khác hoặc nhà thầu và người sử dụng lao động cùng một lúc.
Không cần đi sâu vào chi tiết kỹ thuật, chúng tôi có thể đạt được chức năng này bằng cách cho phép người dùng cập nhật tài khoản của họ bằng cách sử dụng hai hộp chọn cho các vai trò tương ứng — "nhà thầu" và "nhà tuyển dụng" — để người dùng có thể chọn một hoặc cả hai tùy chọn.
Một cách nhanh chóng để đạt được điều này là sử dụng một mảng với các vai trò là khóa, nhưng các tham số mạnh của Rails chỉ cho phép các giá trị vô hướng sau:String , Symbol , NilClass , Numeric , TrueClass , FalseClass , Date , Time , DateTime , StringIO , IO , ActionDispatch::Http::UploadedFile , và Rack::Test::UploadedFile . Như bạn có thể thấy, theo mặc định, mảng, hàm băm và các đối tượng khác không được phép.
Để sử dụng một mảng cho phép nhiều vai trò cho người dùng, chúng ta có thể sửa đổi mã của mình như dưới đây:
Tài liệu Devise về người trợ giúp trình bày chủ đề này chi tiết hơn.
Tiếp theo, chúng ta sẽ tìm hiểu cách tùy chỉnh chế độ xem và bộ điều khiển của Devise.
Tùy chỉnh chế độ xem của Devise
Vì Devise được xây dựng dưới dạng Rails engine nên gần như tất cả các thành phần của nó đều được đóng gói sẵn. Ví dụ điển hình về điều này bao gồm các chế độ xem đăng nhập, đăng ký, cập nhật chi tiết tài khoản, đặt lại mật khẩu, v.v. Tại một thời điểm nào đó trong quá trình xây dựng ứng dụng, bạn có thể cần phải tùy chỉnh các chế độ xem tích hợp này cho phù hợp với nhu cầu của mình.
Bước đầu tiên là tạo chế độ xem bằng lệnh bundle exec rails g devise:views . Khi bạn làm điều đó, các chế độ xem tương ứng sẽ được tạo và đặt trong app/views/devise thư mục:

Hãy sử dụng một ví dụ thực tế về việc tùy chỉnh chế độ xem của Devise. Trong phần trước, chúng ta đã tìm hiểu cách thêm khóa xác thực bổ sung vào bộ khử trùng Devise. Bây giờ chúng ta hãy mở rộng ví dụ đó để thêm username trường vào chế độ xem đăng ký người dùng.
Vì username trường này không có sẵn cho mô hình người dùng mặc định của chúng tôi, chúng tôi sẽ thêm nó bằng bundle exec rails g migration add_column_username_to_user username di cư. Chạy lệnh bundle exec rails db:migrate để bắt đầu di chuyển và thêm cột vào bảng người dùng.
Tiếp theo, mở file đăng ký người dùng mới và chỉnh sửa như sau:
Tạo các chế độ xem Devise theo cách này là ổn nếu bạn đang làm việc với tất cả các chế độ xem. Nhưng giả sử bạn chỉ muốn tùy chỉnh một vài chế độ xem. Làm thế nào bạn có thể làm điều này? Chà, bạn chỉ cần chuyển lệnh tạo danh sách các chế độ xem bạn muốn bằng cách chỉ ra cờ chế độ xem bundle exec rails g devise:views -v sessions registrations . Trong trường hợp này, điều này chỉ tạo ra các chế độ xem được liên kết với quá trình đăng nhập/đăng xuất và các chế độ xem xử lý đăng ký.
Tiếp tục, hãy tìm hiểu sâu hơn về tùy chỉnh Devise bằng cách tìm hiểu cách tùy chỉnh bộ điều khiển và tuyến đường của thư viện.
Tùy chỉnh các bộ điều khiển và tuyến đường phát minh
Việc tùy chỉnh chế độ xem của Devise chỉ có thể giúp bạn tiến xa hơn. Nếu bạn muốn tùy chỉnh thực sự, bạn cần vào bộ điều khiển và tuyến đường của thư viện.
Giả sử chúng tôi muốn gửi email đến quản trị viên của mình để thông báo cho họ về mọi đăng ký người dùng mới trên ứng dụng. (Đây không phải là cách lý tưởng để giải quyết mọi việc, nhưng hãy xem ví dụ này để minh họa điều chúng ta muốn).
Để bắt đầu, chúng ta cần sửa đổi hành động đăng ký của Devise::RegistrationsController . Thông thường, bộ điều khiển của Devise không thể truy cập trực tiếp để chỉnh sửa, do đó, giống như chúng ta đã làm với các chế độ xem, chúng ta có thể tạo chúng như sau:
Phần cuối cùng của lệnh đó là phạm vi - trong trường hợp này là users . Nếu bạn muốn nó là cái gì khác, bạn có thể thay đổi nó cho phù hợp. Khi bạn hoàn tất, bộ điều khiển được tạo sẽ có cấu trúc tương tự như sau:

Tiếp theo, mở tệp tuyến đường và sửa đổi các tuyến đường của Devise để phản ánh những thay đổi trong cấu trúc bộ điều khiển:
Bây giờ hãy mở Users::RegistrationsController mới được tạo và sửa đổi nó để gửi email đến quản trị viên bất cứ khi nào người dùng mới đăng ký:
Như bạn có thể thấy, với quyền truy cập vào bộ điều khiển và hành động của Devise, bạn có thể sửa đổi luồng xác thực của ứng dụng theo bất kỳ cách nào bạn muốn.
Phần tiếp theo:Sử dụng nâng cao Devise
Trong phần đầu tiên của loạt bài gồm hai phần này, chúng ta đã trình bày những kiến thức cơ bản về Devise gem. Chúng tôi đã tìm hiểu về các mô-đun khác nhau của Devise cũng như cách tùy chỉnh chế độ xem và bộ điều khiển của nó.
Trong phần hai, chúng ta sẽ đi sâu vào cách sử dụng Devise nâng cao hơn, bao gồm xác thực API và cách sử dụng OmniAuth với Devise.
Cho đến lúc đó, chúc bạn viết mã vui vẻ!
Tái bút. Nếu bạn muốn đọc các bài đăng của Ruby Magic ngay khi chúng được đăng tải, hãy đăng ký nhận bản tin Ruby Magic của chúng tôi và không bao giờ bỏ lỡ một bài đăng nào!