この記事はウェブクルー Advent Calendar 2023 5日目の記事です。
昨日は@wc-horino さんの「Scala, PlayFramework, Mockitoを使った自動テスト導入」でした。
Rails-deviseとは
Deviseは、Ruby on Railsフレームワークの人気のある認証ライブラリです。ユーザーのサインアップ、サインイン、パスワードのリセットなど、強力なセキュリティ機能および認証機能を簡単に実装できるようなGemライブラリーです。
開発環境情報
# rubyバージョン
$ rbenv versions
* 3.2.2
# railsバージョン、Turbo Frame有効済み
$ rails -v
Rails 7.1.2
参考資料
公式ドキュメント
Github
Rails-deviseのインストールと初期設定
Rails-deviseのインストール
gem "devise"
bundle install
rails g devise:install
deviceをインストールしたら、deviseのconfigファイル(/config/initializers/devise.rb)が作成されました。
今回は特に編集しなくて大丈夫です。
deviseのUserモデルの作成
rails g devise User
userモデルとroutesの記述が自動に追加されました。
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
end
devise_for :users
この一行の追加により、以下のようなルーティングが自動的に設定されます:
サインアップ (/users/sign_up)
ログイン (/users/sign_in)
サインアウト (/users/sign_out)
パスワードリセット (/users/password/new, /users/password/edit など)
Rails.application.routes.draw do
devise_for :users
get "home/index"
root "home#index"
get "up" => "rails/health#show", as: :rails_health_check
# Defines the root path route ("/")
# root "posts#index"
end
マイグレーションファイルでカスタマイズカラムを追加
rails g migration AddColumnToUser
/db/migrate/*****_add_column_to_user.rbファイルが生成されました。
このマイグレーションファイルでfull_name、username、phone_numberのカラムをusersテーブルに追加します。
class AddColumnToUser < ActiveRecord::Migration[7.1]
def change
add_column :users, :full_name, :string
add_column :users, :username, :string
add_column :users, :phone_number, :string
end
end
マイグレーションファイルを実行します。
rails db:migrate
schemaファイルを確認してみると、
full_name、username、phone_numberが無事にusersテーブルに追加されました。
ctiveRecord::Schema[7.1].define(version: 2023_12_04_131204) do
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
+t.string "full_name"
+t.string "username"
+t.string "phone_number"
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
end
コントローラーにdeviseのメソッドなどを登録
参考: https://github.com/heartcombo/devise#strong-parameters
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
# /users/sign_up
devise_parameter_sanitizer.permit(:sign_up, keys: [:username, :phone_number, :full_name])
end
end
ruby7.0以降はTurbo frame機能がデフォルトになっているため、Turboと組み込む必要があります。
class TurboDeviseController < ApplicationController
class Responder < ActionController::Responder
def to_turbo_stream
controller.render(options.merge(formats: :html))
rescue ActionView::MissingTemplate => error
if get?
raise error
elsif has_errors? && default_action
render rendering_options.merge(formats: :html, status: :unprocessable_entity)
else
redirect_to navigation_location
end
end
end
self.responder = Responder
respond_to :html, :turbo_stream
end
deviseのviewsの作成
deviseのデフォルトのビューをカスタマイズするためのファイルがアプリケーション内に生成されます。
/app/views/deviseのフォルダーが生成されて、
今回は/sessions/new.html.erb
と/registrations/new.html.erb
だけを編集します。
rails generate devise:views
<div class="container home-sections d-flex flex-row justify-content-center
align-items-center"
>
<div class="images-section pt-3 d-none d-lg-block"></div>
<div class="login-section pt-3">
<div class="card text-center pt-5" style="width: 23rem;">
<h1>ログイン画面</h1>
<div class="card-body">
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<div class="mb-3 mt-4">
<%= f.email_field :email, class: "form-control", placeholder: "電話番号, ユーザ名, Eメール" %>
</div>
<div class="mb-3">
<%= f.password_field :password, class: "form-control", placeholder: "パスワード" %>
</div>
<%= f.submit "ログイン", class: "btn btn-primary w-100" %>
<% end %>
<% if notice %>
<p class="notice"><%= notice %></p>
<% elsif alert %>
<p class="alert"><%= alert %></p>
<% end %>
<a href="#" class="fs-6 d-block my-4 text-decoration-none"> パスワードを忘れた?</a>
</div>
</div>
<div class="card text-center py-2 mt-3" style="width: 23rem;">
<div class="card-text">
アカウントを持っていない?
<%= link_to "サインアップ", new_user_registration_path, class: "fs-6 my-4 text-decoration-none text-info" %>
</div>
</div>
</div>
</div>
<div class="container home-sections d-flex flex-row justify-content-center
align-items-center"
>
<div class="login-section pt-3">
<div class="card text-center pt-5 mx-auto" style="width: 23rem;">
<h1>サインアップ画面</h1>
<div class="card-body">
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<div class="mb-3 mt-4">
<%= f.email_field :email, class: "form-control", placeholder: "電話番号、Eメール" %>
</div>
<div class="mb-3 mt-4">
<%= f.text_field :full_name, class: "form-control", placeholder: "お名前" %>
</div>
<div class="mb-3 mt-4">
<%= f.text_field :username, class: "form-control", placeholder: "ユーザ名" %>
</div>
<div class="mb-3">
<%= f.password_field :password, class: "form-control", placeholder: "パスワード" %>
</div>
<div class="mb-3">
<%= f.password_field :password_confirmation, class: "form-control", placeholder: "パスワード確認" %>
</div>
<%= f.submit "サインアップ", class: "btn btn-primary w-100" %>
<% end %>
<% if notice %>
<p class="notice"><%= notice %></p>
<% elsif alert %>
<p class="alert"><%= alert %></p>
<% end %>
</div>
</div>
<div class="card text-center py-2 mt-3 mx-auto" style="width: 23rem;">
<div class="card-text">
既にアカウントを持っている?
<%= link_to "サインイン", new_user_session_path, class: "fs-6 my-4 text-decoration-none text-info" %>
</div>
</div>
</div>
</div>
開発環境で確認
サンプルをご参考ください。
- ユーザ登録ページ http://localhost:3000/users/sign_up
- ログインページ http://localhost:3000/users/sign_in
- トップページ http://localhost:3000
終わりに
deviseはRuby on Railsアプリケーションにおいて、ユーザー認証とセッション管理の実装を驚くほど簡単で同時に豊富な機能を提供しています。開発者はセキュリティに焦点を当てることなくてアプリケーションのコア機能に専念できます。ぜひ試して見てください。
明日は@wchikarusato さんの「obsidianを使って1週間を振り返る方法」になります。
お楽しみにしてください。