WEBサイト制作
2015.12.02
Ruby on Rails4で簡単なログイン機能の実装方法
今回はユーザーテーブルを作成しメールアドレスとパスワードでログインできる機能を実装します。
新規プロジェクトでユーザーテーブルまでを作成したところから説明していきます。
ユーザーテーブルを作成するまではCentOS6での環境構築後にRuby on Rails4でhello world! 的なアプリケーションを作成する方法。を参照してください。
usersテーブルにpasswordカラムを追加
・マイグレーション作成
$ bundle exec rails g migration addPasswordDigestToUsers password_digest:string
上記を行うと既存カラムの最後に新しいカラムができてしまいます。
emailカラムの後にpasswordを入力させたいのでマイグレーションを少し修正します。
※SQLiteではこれは効かないようで常に末尾に追加されます
db/migrate/20151201xxxxxx_add_password_digest_to_users.rb
class AddPasswordDigestToUsers < ActiveRecord::Migration
def change
# :after => :email を追加
add_column :users, :password_digest, :string, :after => :email
end
end
・フィクスチャにテストデータを投入する
テストデータにパスワードを追加しておかないと誰もログインできないので各ユーザーのemailの下にpassword_digestを追加します。 ※password_digestはハッシュ値ですtest/fixtures/users.yml
user_1:
id: 1
name: "Test Taro"
email: "test@imd-net.com"
password_digest: $2a$10$VWjalZaXZcp8TJpjS3U9de8osH7PwVCOpMXFWxomFkfaIHB7oUERG
・databaseを一度削除してフィクスチャの流し込みを実行する
$ bundle exec rake db:migrate:reset
$ bundle exec rake db:fixtures:load
Userモデルにパスワードを扱うための記述を追加
Userモデルにhas_secure_passwordを追加する
※これを追加するとパスワードの暗号化や認証の機能が追加されます。app/models/user.rb
class User < ActiveRecord::Base
# 以下を追加することで passwordとpassword_confirmationが自動で追加され、存在チェックのバリデーションも設定されます。
そして、password_digestへ暗号化されて登録されます。
has_secure_password
end
暗号化のためにGemfileに下記gemを有効化してbundle installする
gem 'bcrypt', '~> 3.1.7'
bundle install
ログインチェック処理追加
全コントローラの共通クラスに、ログインしてない場合は強制的にログイン画面に遷移する処理を追加する
app/controllers/application_controller.rbclass ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
### ここから追加 ###
before_action :user_logged_in? #ログインチェックの事前認証
def reset_user_session
session[:user] = nil
@current_user = nil
end
def user_logged_in?
user_id = session[:user]
if user_id then
begin
@current_user = User.find(user_id)
rescue ActiveRecord::RecordNotFound
reset_user_session
end
end
# current_userが取れなかった場合はログイン画面にリダイレクト
unless @current_user
flash[:referer] = request.fullpath
redirect_to "/login"
end
end
### ここまで追加 ###
end
上記までを行えばlocalhost:3000/usersにアクセスしたら/loginにリダイレクトされることを確認できます。
ログイン用のコントローラを作成
ログイン画面の表示やログイン処理を実装するコントローラを作成します。rails generate で自動作成
app/controllers/application_controller.rb$ bundle exec rails g controller session index --no-assets
sessionというコントローラ名でindexだけ作作成。css、jsは使わないので--no-assetsとします。
リソースでセッションを作成する。
config/routes.rbresources :session, path: "login", only: [:index, :create] do
collection do
delete '/', to: "session#delete"
end
end
コントローラ編集 1
ログイン画面表示するときはログインチェック不要。 セッションコントローラに以下を追加して、全コントローラ共通のbefore_actionをスキップさせます。 app/controllers/session_controller.rbskip_before_action :user_logged_in?
ログイン画面表示時に使用する変数を設定する処理を追加する
app/controllers/session_controller.rbdef index
@user = User.new
end
ビュー編集
app/views/session/index.html.erb<h1>Login</h1>
<%= form_for(@user, url: session_index_path, method: :post) do |f| %>
<% if flash[:error] %>
<div id="error_explanation">
<h2>ユーザー名またはパスワードが違います</h2>
</div>
<% end %>
<%= hidden_field_tag :referer, flash[:referer] %>
<div class="field">
<%= f.label :email %>
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :password %>
<%= f.password_field :password %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
ここまで行ったらlocalhost:3000/usersにアクセスするとログイン画面にリダイレクトされます。コントローラ編集 2
sessions_controllerのcreateメソッドを実装してログインできるようにします。ログアウト用処理のdeleteも実装。
app/controllers/session_controller.rb
def create
@user = User.find_by(email: user_params[:email])
if @user && @user.authenticate(user_params[:password])
reset_user_session
session[:user] = @user.id
redirect_to params[:referer].present? ? params[:referer] : users_path
else
@user = User.new
flash.now[:referer] = params[:referer]
flash.now[:error] = true
render :index
end
end
def delete
reset_user_session
redirect_to session_index_url
end
private
def user_params
params.require(:user).permit(:email, :password)
end
ログアウト用のリンクを追加レイアウトにログアウト用のリンクを追加する
<%= yield %>の上に以下を追記する。app/views/layouts/application.html.erb
<%= link_to "Logout", session_index_path, method: :delete %>
完成した結果は下記のようになります
まとめ
今回の内容で簡単なメールアドレスとパスワードでのログイン機能が実装できました。今回はBootstrapでレイアウトを整えませんでしたが、やはり見栄えが寂しく感じます。 Ruby on Rails4でレイアウトを整えたい方はRuby on Rails4でransackを使った検索機能の実装を参考にしていただければ幸いです。