目的
Ruby on Railsでよく使われている認証周りのgemライブラリーであるdeviseをつかってログイン機能を用いる。 deviseの標準ではemailに基づいてユーザを区別しているが、usernameでユーザを区別できるようにする。
参考
環境
% lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 18.04.1 LTS Release: 18.04 Codename: bionic % ruby -v ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux] % gem -v 2.7.7 % rails -v Rails 5.2.1
新しいプロジェクトの生成
% rails new prac_devise --skip-bundle % cd prac_devise % cp -p Gemfile Gemfile.org % vi Gemfile
Gemfileの中身を以下のように変更する。
% diff Gemfile.org Gemfile 17c17 < # gem 'mini_racer', platforms: :ruby --- > gem 'mini_racer', platforms: :ruby 62c62 < gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] --- > #gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] 63a64 > gem 'devise'
bundleを実行する。
% bundle install --path vendor/bundle
ダミーモデルの作成
今回はHomeコントローラーを作成し、indexにアクセスする際にはログインなし、showにアクセスする場合はログインありに設定する。このためにHomeコントローラーを作成する。
% rails g controller Home index show
このアプリケーションのトップページをHome#indexとする。
% vi config/routes.rb
中身に以下を加える。
root to: "home#index"
Deviseのインストール
このアプリケーションでdeviseが使えるように設定する。
% rails g devise:install
今回はUserモデルを認証対象のモデルとする。
% rails g devise User
devise用のviewを app/views/devise 以下にコピーする。
% rails g devise:views % ls app/views/devise/ confirmations/ passwords/ sessions/ unlocks/ mailer/ registrations/ shared/
メールに記述するURLの設定
config/environments/development.rb に以下を加える。
# mailer setting config.action_mailer.default_url_options = {host: 'localhost', port: 3000}
エラーメッセージを表示できるようにする。
app/views/layouts/application.html.erbに以下を加える。
〜省略〜 <body> <p class="notice"><%= notice %></p> #この行を追加 <p class="alert"><%= alert %></p> #この行を追加 <%= yield %> </body> 〜省略〜
User#showへのアクセスをログインした場合のみにする
app/controllers/home_controller.rb にフィルターをかける。
class HomeController < ApplicationController before_action :authenticate_user!, only: :show #この行を追加 def index end 〜省略〜
試してみる
% rails db:migrate % rails s (終了させるときは Ctrl + c)
- http://0.0.0.0:3000/ にアクセスするとHome#indexの内容が表示される(デフォルトでは「Home#index Find me in app/views/home/index.html.erb」が表示される)。
- http://0.0.0.0:3000/home/index にアクセスすると上と同じ画面が表示される
- http://0.0.0.0:3000/home/show にアクセスするとログイン画面に飛ばされる
識別キーをusernameに変更する
まず、usersテーブルにusernameを追加する。
% rails g migration add_username_to_users username:string
db/migrate/xxxxxxxxx_add_username_to_users.rb を編集し、usernameをインデックスとして使えるように以下を追加する。
class AddUsernameToUsers < ActiveRecord::Migration[5.2] def change add_column :users, :username, :string add_index :users, :username, unique: true #この行を追加 end end
上記の変更を反映させる。
% rails db:migrate
識別キーをusernameに変更する。 config/initializers/devise.rbに以下の行を加える。
〜 省略 〜 # You can also supply a hash where the value is a boolean determining whether # or not authentication should be aborted when the value is not present. # config.authentication_keys = [:email] config.authentication_keys = [:username] #この行を追加 〜 省略 〜
ログイン(sign in)、ユーザ登録(sign up)、情報変更のページでusernameを入力できるように変更する。
ログインページ(app/views/devise/sessions/new.html.erb)の編集。
変更前 <%= f.label :email %><br /> <%= f.email_field :email, autofocus: true, autocomplete: "email" %> 変更後 <%= f.label :username %><br /> <%= f.email_field :username, autofocus: true %>
ユーザ登録ページ(app/views/devise/registrations/new.html.erb) の編集。
変更前 <%= f.label :email %><br /> <%= f.email_field :email, autofocus: true, autocomplete: "email" %> 変更後 <%= f.label :username %><br /> <%= f.text_field :username, autofocus: true %>
情報変更のページ(app/views/devise/registrations/edit.html.erb)の編集。
変更前 <%= f.label :email %><br /> <%= f.email_field :email, autofocus: true, autocomplete: "email" %> 変更後 <%= f.label :username %><br /> <%= f.text_field :username, autofocus: true %>
usernameにvalidateを設定およびemailを利用しないことを設定する。
app/models/user.rb について以下を追加する。
class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable # この行以下を追加する # usernameの制約 validates :username, uniqueness: {case_sensitive: :false}, length: {minimum: 4, maximum: 20}, format: {with: /\A[a-z0-9]+\z/, message: "ユーザ名は半角英数字です"} # emailを識別キーとして使わない場合の処理 def email_required? false end def email_changed? false end def will_save_changed_to_email? false end # 追加ここまで end
strong_parameterの設定
Ruby on Rails4よりStrong Parameterという仕組みが導入されている。これの設定が必要。 app/controllers/application_controller.rb に以下を加える。
# deviceのコントローラーのときに、下記のメソッドを呼ぶ before_action :configure_permitted_parameters, if: :devise_controller? protected # usernameを追加する 参考:https://github.com/plataformatec/devise#strong-parameters def configure_permitted_parameters devise_parameter_sanitizer.permit :sign_up, keys: [:usrname] devise_parameter_sanitizer.permit :account_update, keys: [:username] end
試してみる
% rails db:migrate % rails s (終了させるときは Ctrl + c)
- http://0.0.0.0:3000/home/index にアクセスすると上と同じ画面が表示される
- http://0.0.0.0:3000/home/show にアクセスするとログイン画面に飛ばされる