rails 基本的なログインシステム Part1
作ったもの
HPを作成したのですが、管理人だけがページを閲覧しながら記事などの投稿や編集、削除を行えるようにしたかったので、動画のようにログイン後に同じnewsのページに移動すると投稿機能が使えるようになっています。この記事では「ログイン機能」の実装について書いていきます。
すること
- 管理人をユーザーモデルで作成
- ログインのcontroller作成やルーティング設定
- ログインのビュー作成
- ログイン機能作成
- ちょっと発展機能を加える
- ログイン機能を実装したことによって利用できること
長くなりそうなのでこの記事では3番目のログインのビュー作成までを書いていこうと思います。
1.管理人をユーザーモデルで作成
Userモデルの中身はこんな感じ
パスワードは暗号化して、メッセージダイジェストで保存したいのでgemの「bcrypt」を使います。
gem 'bcrypt'
bundle install
作っていきます。
rails generate model User name:string email:string password_digest:string
マイグレーションファイルはこんな感じ。
20191221045711_create_users.rb class CreateUsers < ActiveRecord::Migration[5.1] def change create_table :users do |t| t.string :name t.string :email t.string :password_digest t.timestamps end end end
rails db:migrate
パスワードをダイジェストで保存するにはユーザーのモデルファイルに下記のようにhas_secure_passwordを追記
app/models/user.rb class User < ApplicationRecord has_secure_password end
これでpassword_digestカラムに暗号化されたパスワードが保存されます。
Userを作成する際は下記のように:passwordと:password_confirmationの二つを入力しなくてはならない。
User.new(name : 'aaa', email: 'aaa.example.com', password: 'aaa', password_confirmation: 'aaa')
今回作成したHPではユーザーは管理者一人のみなので、サインアップページなどを作成してユーザーを増やすことはありません。
なので管理者のユーザー一つをseeds.rbで作っておきます。
seeds.rb User.create(name: "Ryo", email: "ryo@example.com", password: "password", password_confirmation: "password")
rails db:seed
細かい設定は後にして、とりあえず管理者ユーザーは完成しました!
ログインのcontroller作成やルーティング設定
ログイン画面表示はnewアクション
ログイン処理はcreteアクション
ログアウト処理はdestroyアクション
をそれぞれ使います。
早速コントローラー作成
rails generate controller sessions new create destroy
ファイルはこんな感じ
class SessionsController < ApplicationController def new end def create end def destroy end end
続いてルーティングの設定
routes.rb Rails.application.routes.draw do get '/login', to: 'sessions#new' post '/login', to: 'sessions#create' delete '/logout', to: 'sessions#destroy' end
このような記述で、/loginや/logoutでアクションが呼び出せますし、login_path,logout_pathメソッドも使えるようになりました。
3.ログインのビュー作成
newアクションを呼び出した時のビューをnew.html.erbに書いていきます。
app/views/sessons/new.html.erb <div id="form"> <h1>Login</h1> <%= form_for(:session, url: login_path) do |f| %> <div class="form-item"> <p class="formLabel">Email</p> <%= f.email_field :email, class: 'form-style form-control',autocomplete: 'off' %> </div> <div class="form-item"> <p class="formLabel">Password</p> <%= f.password_field :password, class: 'form-style form-control' %> </div> <%= f.submit "Log in", class: "login pull-right" %> <% end %> </div>
form_for(:session, url: login_path)と書くことで送信ボタンを押した時に、sessionsコントローラーのcreateアクションでparams[:session][:email]email、params[:session][:password]を使って、ログインフォームで入力されたメールアドレスとパスワードを取得できます。
どう利用するかは後編で書きます。
CSSデザインはお好みで
僕の場合こちらを参考にしました。↓↓
https://codepen.io/Timurtek/pen/LblHd/
アラートも表示させたいのでそのためのパーシャルも用意しておきます。
app/views/sessions/_alert.html.erb <% if flash[:danger] %> <% flash.each do |message_type, message| %> <div class="alert alert-<%= message_type %>"> <%= message %> </div> <% end %> <% else %> <p class="form-msg">こちらは管理人専用ページです。</p> <% end %>
追加します。
app/views/sessions/new.html.erb <div id="form"> <h1>Login</h1> <%= render 'sessions/alert' %> (中略) </div>
ログイン失敗にアラートが表示された状態でログイン画面に戻るように設定。
class SessionsController < ApplicationController def new end def create if 入力された情報のユーザーが存在するか? #ログイン処理を書きます else flash.now[:danger] = '有効なメールアドレス、またはパスワードではありません。' render 'new' end end def destroy end end
これでログイン失敗時の動きが完成しました。
具体的なログイン機能は次回。