認証はセキュリティを考えなければなんとでもなりますが、そこは避けては通れないのでライブラリに頼ったほうが良いということで割とメジャーそうなdeviseを触ってみました。基本的なMVCの作り方はわかるものとしてdeviseに関する部分にフォーカスします。ここではコントローラー名はLoginTestとします。
まず必要な設定とインストールをします。
Gemfileに下記を追加
gem 'devise'
そしてインストール
>bundle install >rails generate devise:install Running via Spring preloader in process 13350 create config/initializers/devise.rb create config/locales/devise.en.yml
deviseによるgenerateができるのでこれでテーブル作成を作成します。モデルのgenerateに近い記述ですね。ここではaccountとします。あとマイグレーション。
>rails generate devise account Running via Spring preloader in process 20187 invoke active_record create db/migrate/20180327082026_devise_create_accounts.rb create app/models/account.rb invoke test_unit create test/models/account_test.rb create test/fixtures/accounts.yml insert app/models/account.rb route devise_for :accounts >rails db:migrate
主なファイルは以下のようなコードが生成されます。
account.rb
class Account < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable end
routes.rb
Rails.application.routes.draw do devise_for :accounts
migrate/xxxx_devise_create_accounts.rb
# frozen_string_literal: true class DeviseCreateAccounts < ActiveRecord::Migration[5.1] def change create_table :accounts do |t| ## Database authenticatable t.string :email, null: false, default: "" t.string :encrypted_password, null: false, default: "" ## Recoverable t.string :reset_password_token t.datetime :reset_password_sent_at ## Rememberable t.datetime :remember_created_at ## Trackable t.integer :sign_in_count, default: 0, null: false t.datetime :current_sign_in_at t.datetime :last_sign_in_at t.string :current_sign_in_ip t.string :last_sign_in_ip ## Confirmable # t.string :confirmation_token # t.datetime :confirmed_at # t.datetime :confirmation_sent_at # t.string :unconfirmed_email # Only if using reconfirmable ## Lockable # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts # t.string :unlock_token # Only if unlock strategy is :email or :both # t.datetime :locked_at t.timestamps null: false end add_index :accounts, :email, unique: true add_index :accounts, :reset_password_token, unique: true # add_index :accounts, :confirmation_token, unique: true # add_index :accounts, :unlock_token, unique: true end end
ログイン処理
まず表示部分を用意します。ログイン画面に行くためのページを用意。
view/login_test/index.html.erb
<!-- log in --> <div><%= link_to 'Log in! >>'.html_safe, {action:'login'} %></div>
ログインページへ行くためにloginアクションへのリンクを作ります。そのためloginページも作っておきます。
view/login_test/login.html.erb
<h1><%= @account.email %></h1> <%= @msg %>
ログインしたら@accountと@msgを渡すようにしておきます。
続いてコントローラーを用意します。ログインページに行く用とログイン画面用のアクションを用意します。
ここで重要なのがbefore_actionとして認証チェックを挟むコードを入れることです。下のコードだとloginアクションが呼び出された時認証済みかチェックしてくれて、認証されていないときは勝手に認証ページ(sign_up)へ飛ばしてくれます。
authenticate_accountはdeviseでaccountを作った時に作られます。
controllers/login_test_controller.rb
class LoginTestController < ApplicationController # check authentification before_action :authenticate_account!, only: :login def index end def login @account = current_account @msg = 'login date: ' + @account.current_sign_in_at.to_s end end
最後にルーティング
get 'login_test/index' get 'login_test/login'
以上で完了です。login_test/indexからloginアクションをクリックすると最初はsign_upページへ飛ぶはずです。最初はアカウントがないので下の方にあるsignupボタンを押して1つアカウントを追加する必要があります。
ログアウト処理
ログインしたのでログアウトも必要です。このためトップページであるindexにログアウト用のリンクを追加します。
こちらはページを用意しません。
重要なのはsign_out用のパスがすでに設定されているのでこれを使いdeleteメソッドでアクセスしてあげる必要があります。
view/login_test/index.html.erb
<!-- log in --> <div><%= link_to 'Log in! >>'.html_safe, {action:'login'} %></div> <!-- log out --> <div><%= link_to "Sign out >>".html_safe, destroy_account_session_path, method: :delete %></div>
このリンクを押せばログアウトできます。
ログインページのデザイン
deviseの画面は全然簡素なものです。実際のウェブサービスではまず使えないのでカスタマイズしてやる必要があります。
そのための方法がある程度用意されています。以下のコマンドでviewが生成されるのでこれを直します。
>rails generate devise:views Running via Spring preloader in process 34454 invoke Devise::Generators::SharedViewsGenerator create app/views/devise/shared create app/views/devise/shared/_links.html.erb invoke form_for create app/views/devise/confirmations create app/views/devise/confirmations/new.html.erb create app/views/devise/passwords create app/views/devise/passwords/edit.html.erb create app/views/devise/passwords/new.html.erb create app/views/devise/registrations create app/views/devise/registrations/edit.html.erb create app/views/devise/registrations/new.html.erb create app/views/devise/sessions create app/views/devise/sessions/new.html.erb create app/views/devise/unlocks create app/views/devise/unlocks/new.html.erb invoke erb create app/views/devise/mailer create app/views/devise/mailer/confirmation_instructions.html.erb create app/views/devise/mailer/email_changed.html.erb create app/views/devise/mailer/password_change.html.erb create app/views/devise/mailer/reset_password_instructions.html.erb create app/views/devise/mailer/unlock_instructions.html.erb
views/devise以下にたくさんファイルが作られるので多少面倒ですががんばって見栄えのよい画面を作りましょう。