deviseを用いたユーザ認証作成 -Rails奮闘記①-
本記事の概要
本記事は、私がRuby on Rail(Rails, RoR)を用いたWebアプリケーションを作る過程を示したものです。 Railsの勉強も兼ねているため、間違いなどもあった場合はご指摘いただけると大変嬉しいです!
- OS: Mac OS 10.12.6
- Ruby: 2.5.0
- Ruby on Rails: 5.1.4
Devise を用いた基本的なユーザ認証の作成まで
Railsプロジェクトを作成する
1. Githubの準備
$ git clone https://github.com/[Githubのユーザ名]/[プロジェクト名].git $ cd [プロジェクト名]
2. Gemfileという雛形ファイルが作成
$ bundle init
3. Gemfileに書き込む
gem "rails","5.1.4"
4. ルートディレクトリ下のvendor/bundle
ディレクトリにインストール
$ bundle install --path vendor/bundle
5. Rails プロジェクトを作成する
$ bundle exec rails new .
devise
の初期設定
6. devise
をインストール
# Gemfile gem 'devise'
$ bundle install --path vendor/bundle
7. deviseの設定ファイルを生成
config/initializers/devise.rb
と config/locales/devise.en.yml
ができる
$ rails g devise:install $ bundle exec rails g devise:install Running via Spring preloader in process 84346 create config/initializers/devise.rb create config/locales/devise.en.yml =============================================================================== Some setup you must do manually if you haven't yet: 1. Ensure you have defined default url options in your environments files. Here is an example of default_url_options appropriate for a development environment in config/environments/development.rb: config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } In production, :host should be set to the actual host of your application. 2. Ensure you have defined root_url to *something* in your config/routes.rb. For example: root to: "home#index" 3. Ensure you have flash messages in app/views/layouts/application.html.erb. For example: <p class="notice"><%= notice %></p> <p class="alert"><%= alert %></p> 4. You can copy Devise views (for customization) to your app by running: rails g devise:views ===============================================================================
8. deviseのメール送信時のホスト名を指定
# config/environments/development.rb Rails.application.configure do ... # mailer setting config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } end
9. 実際のControllerやViewを作成 ここでは、Homeコントローラーと、indexページとshowページを追加した。
$ rails g controller Home index show
10. ログアウト時などのリダイレクト先として、root_url
の指定する
# config/routes.rb Rails.application.routes.draw do root to: "home#index" end
11. エラーメッセージ(flash
メッセージ)の表示領域の設定
<!-- app/views/layouts/application.html.erb --> <!DOCTYPE html> <html> <!--(省略)--> <body> <p class="notice"><%= notice %></p> <p class="alert"><%= alert %></p> <%= yield %> </body> </html>
12. deviseのモデルを作成
$ rails g devise User invoke active_record create db/migrate/[yyyymmddhhmmss]_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
13. マイグレートを実施 マイグレーションとは、SQLを書くことなくRubyでデータベース内にテーブルを作成すること。
$ rake db:migrate
14. Homeのshow画面へのアクセス制限を追加
ステップ13までは、ログインしていない状態でshow画面 | http://localhost:3000/home/showにアクセス可能となってしまっている。
# app/controllers/home_controller.rb class HomeController < ApplicationController # ユーザがログインしていないと"show"にアクセスできない before_action :authenticate_user!, only: :show def index end # (省略) end
username
で認証できるようにする
15. テーブルにusername
を追加
$ rails g migration add_username_to_users username:string
16. indexの追加と一意制約を追加
# db/migrate/[yyyymmddhhmmss]_add_username_to_users.rb class AddUsernameToUsers < ActiveRecord::Migration[5.1] def change add_column :users, :username, :string add_index :users, :username, unique: true end end
17. マイグレートを実施
$ rake db:migrate
18. 認証キーをusername
へ
# config/initializers/devise.rb # (省略) # ==> Configuration for any authentication mechanism # Configure which keys are used when authenticating a user. The default is # just :email. You can configure it to use [:username, :subdomain], so for # authenticating a user, both parameters are required. Remember that those # parameters are used only when authenticating and not when retrieving from # session. If you need permissions, you should implement that in a before filter. # 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] # (省略)
19. UserモデルにValidateを追加
username
には、以下のバリデーションを追加した。
username
が大文字小文字の区別をせずにuniqueであること- 文字数が4 - 20文字であること
username
は半角英数字であること
# app/models/user.rb class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable # usernameのバリデーション validates :username, uniqueness: { case_sensitive: :false }, length: { minimum: 4, maximum: 20 }, format: { with: /\A[a-z0-9]+\z/, message: "ユーザー名は半角英数字です"} end
20. ログイン画面のemailをusername
の入力フィールドに変更
<!-- app/views/devise/sessions/new.html.erb --> <h2>Log in</h2> <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %> <div class="field"> <%= f.label :username %><br /> <%= f.text_field :username, autofocus: true %> </div> <!--(省略)--> <% end %> <%= render "devise/shared/links" %>
21. サインアップ画面もusername
の入力フィールドに対応
<!-- app/views/devise/registrations/new.html.erb --> <h2>Sign up</h2> <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> <%= devise_error_messages! %> <div> <%= f.label :username %><br /> <%= f.text_field :username, autofocus: true %> </div> <!--(省略)--> <% end %> <%= render "devise/shared/links" %>
22. プロフィール変更画面もusername
の入力フィールドに対応
<!-- app/views/devise/registrations/edit.html.erb --> <h2>Edit <%= resource_name.to_s.humanize %></h2> <%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %> <%= devise_error_messages! %> <div> <%= f.label :username %><br /> <%= f.text_field :username, autofocus: true %> </div> <!--(省略)--> <% end %>
23. app/controllers/application_controller.rb
の追記
Publifyでユーザー登録するとCan't be blankエラーの対応
# app/controllers/application_controller.rb class ApplicationController < ActionController::Base # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. protect_from_forgery with: :exception # deviceのコントローラーのときに、下記のメソッドを呼ぶ before_action :configure_permitted_parameters, if: :devise_controller? protected def configure_permitted_parameters added_attrs = [:username, :email, :password, :password_confirmation, :remember_me] devise_parameter_sanitizer.permit :sign_up, keys: added_attrs devise_parameter_sanitizer.permit :account_update, keys: added_attrs end end
まとめ
本記事は、以下の記事を参考にまとめました。