Gem devise là một thư viện rất phổ biến trong ruby on rails. Đây là một gem rất linh hoạt trong việc hỗ trợ xác thực người dùng. Nó hỗ trợ hầu hết tất cả mọi việc bạn cần trong việc quản lí và xác thực người dùng trong hệ thống của bạn. Việc login bằng facebook, twitter, google... thì thư viện này cũng hỗ trợ, rất dễ để sử dụng chức năng login qua các mạng xã hội. Trong bài viết này mình sẽ hướng dẫn các bạn tạo một app nho nhỏ để login thông qua google.
Tạo mới project bằng cửa sổ console
rails new demo_login_google -d mysql
Tiếp theo ta chạy: rails db:create để tạo database trong MySQL
Sau đó chúng ta sẽ cấu hình lại trong database.yml bằng cách đánh mật khẩu của root vào trong file này
default: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: YOUR PASSWORD socket: /var/run/mysqld/mysqld.sock development: <<: *default database: demo_login_google_development test: <<: *default database: demo_login_google_test production: <<: *default database: demo_login_google_production username: demo_login_google password: <%= ENV['DEMO_LOGIN_GOOGLE_DATABASE_PASSWORD'] %>
Chạy thử lên, ta sẽ khởi tạo xong project rails
Tiếp theo, thêm vào Gemfile các gem sau:
gem "devise"
gem "omniauth"
gem "omniauth-google-oauth2"
Sau đó ta bundle lại: bundle và chạy lệnhrails generate devise:install
Tiếp theo, bạn cần phải thiết lập các tùy chọn URL mặc định cho Devise mailer. Dưới đây là một cấu hình trong file config/environments/development.rb
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
Sau khi add gem devise vào bước tiếp theo cần generate model sử dụng dem devise cho hệ thống. Ở bài viết lần này mình quản lý User nên mình sẽ đánh lệnh
rails generate devise User
Đây là các file sau khi chạy xong lệnh trên
invoke active_record create db/migrate/20190615092748_devise_create_users.rb create app/models/user.rb invoke test_unit create test/models/user_test.rb create test/fixtures/users.yml insert app/models/user.rb route devise_for :users
Trong route sẽ tự động sinh ra
Rails.application.routes.draw do devise_for :users end
Ta có thể chạy rails routes lên để kiểm tra đường dẫn đã được thành công hay chưa.
Ta sẽ tạo ra các view cho User bằng lệnh
rails generate devise:views
Để tạo các controller trong devise ta dùng lệnh
rails generate devise:controllers users
Các thư mục controllers của user sẽ được sinh ra trong controllers/users/
create app/controllers/users/confirmations_controller.rb create app/controllers/users/passwords_controller.rb create app/controllers/users/registrations_controller.rb create app/controllers/users/sessions_controller.rb create app/controllers/users/unlocks_controller.rb create app/controllers/users/omniauth_callbacks_controller.rb
OK vậy là chúng ta đã cài đặt xong các phần cơ bản trong devise, tiếp theo ta sẽ cài đặt google app
Đầu tiên bạn vào đường link sau https://console.developers.google.com Tạo mới một project Sau khi đã có project của mình, thì bạn cần lựa chọn api để đẳng nhập trên trang web của mình. Bạn enable 2 thứ đó là Gmail API và Contact API Tiếp theo bạn create credentials oauth client id và điền những thông tin sau: http://localhost:3000/users/auth/google_oauth2/callback
Ok bạn create và bạn sẽ nhận được client ID và client secret, bạn nên sao chép 2 mã trên để sử dụng.
Vậy là đã tạo xong được google app ^^
Bạn vào config/initializers/devise.rb và ghi cho mình đoạn code sau
config.omniauth :google_oauth2, ENV["google_client_id"], ENV["google_client_secret"]
Trong đó ENV["google_client_id"], ENV["google_client_secret"] là hai biến môi trường mình đã khởi tạo, tương ứng với mỗi biến môi trường kia là 2 đoạn mã mà mình đã lấy được ở phần 3.
Để cài đặt biến môi trường bạn hãy tìm hiểu gem figaro
Trong routes.rb thêm dòng sau
devise_for :users, controllers: { omniauth_callbacks: "users/omniauth_callbacks" }
Trong /app/models/user.rb
class User < ApplicationRecord devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable, :omniauthable, omniauth_providers: [:google_oauth2] def self.from_omniauth(access_token) data = access_token.info user = User.where(email: data['email']).first if user user else user = User.create(username: data['name'], email: data['email'], password: Devise.friendly_token[0,20], uid: access_token[:uid], provider: access_token[:provider] ) end end end
Tiếp theo ta trong app/controllers/user/omniauth_callbacks_controller.rb , thêm đoạn code sau
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController def google_oauth2 @user = User.from_omniauth(request.env['omniauth.auth']) if @user.persisted? flash[:notice] = I18n.t 'devise.omniauth_callbacks.success', kind: 'Google' sign_in_and_redirect @user, event: :authentication else session['devise.google_data'] = request.env['omniauth.auth'].except(:extra) # Removing extra as it can overflow some session stores redirect_to new_user_registration_url, alert: @user.errors.full_messages.join(" ") end end end
Tiếp theo ta sử dụng một đường link để đăng nhập bằng google. Trong views/devise/sessions/new.html.erb thêm dòng sau
<%= link_to "Login by google", user_google_oauth2_omniauth_authorize_path %>
Thêm các trường trong csdl để lưu lại thông tin của người đăng nhập và sử dụng chức năng đăng nhập của google
rails generate migration add_omniauth_to_users provider:string uid:string
rails db:migrate
Ok vậy là ta đã hoàn thành tạo app nho nhỏ về việc login google thông qua gem omniauth. Giờ chỉ cần rails s lên và cảm nhận nhé