くるみ
- Railsでログイン機能を簡単に実装したい
- bcryptの使い方を知りたい
という方に向けてbcryptを使ってログイン機能を実装する方法をまとめました。
自分の備忘録代わりでもありますが、参考になれば幸いです⸝⸝- ̫ -⸝⸝
お品書き
ログイン機能を実装するまでの手順
手順はいたってシンプルかつ簡単です。
くるみ
bcryptを使ってログイン機能を実装する方法
bcryptは、パスワードを安全に扱うためのgemパッケージです。そのbcryptをまずインストールしていきます。
bcryptをインストール
# Use ActiveModel has_secure_password
gem 'bcrypt', '~> 3.1.7'
Gemfileの上の箇所のコメントアウトを外します。
bundle install
Bundlerでインストールしてあげます。
パスワード用のカラムを追加
bin/rails g migration AddUsers1
まずマイグレーションを生成してあげます。ブログ主の場合はUserにパスワードを設定したいので、User用のモノを。
class AddUsers1 < ActiveRecord::Migration[5.2]
def change
add_column :users, :password_digest, :string
end
end
Userテーブルにpassword_digestというカラムを追加します。
パスワードを扱う際にはこの名前である必要があるそうです。
bin/rails db:migrate
マイグレーションを実行してあげます。
「has_secure_password」を記述
お次はUser.rbに以下のように書いてあげます
class User < ApplicationRecord
has_secure_password
(以下略)
この「has_secure_password」はパスワードを扱うためのおまじない的なものです。
書いてあげる事によって、
- password
- password_confirmation(確認用)
以上の二つがUserクラスに追加されます。
どちらも同じ値かつ空であってはいけない、というバリデーションがデフォルトで設定されます。
パスワードを保存
User.create!(省略, password:"パスワード", password_confirmation:"パスワード")
Railsコンソールで、実際に上の二つのカラムの値も指定し保存できればOK。
コントローラーを作る
ログインのためのコントローラーを作ります。
resource :login ,only: [:create, :destroy]
まずroute.rbに以上のように記述してあげます。
bin/rails g controller logins
そしたらloginsコントローラーを作っちゃいましょう
class LoginsController < ApplicationController
def create #ログイン
user=User.find_by(login_id:params[:login_id])
if user && user&.authenticate(params[:password])
session[:user_id]=user.id
flash.alert="ログインに成功しました"
else
flash.alert="ログインに失敗しました"
redirect_to("/")
end
end
def destroy #ログアウト
session.delete(:user_id)
redirect_to("/")
end
end
LoginsControllerはこんな感じ。
4行目でパスワードが合っているかをチェックし、5行目でセッションデータに値を入れログインを実現しています。
authenticatesメソッドは引数で指定したパスワードが合っていればモデルオブジェクトを返してくれます。
ブログ主
フォームを用意する
<%=form_tag :session,id:"login_form" do%>
<div>
<label>id:</label>
<input type="text" name="login_id">
</div>
<div>
<label>パスワード</label>
<input type="text" name="password">
</div>
<div>
<input type="submit" value="ログイン">
</div>
<%end%>
上のコントローラーで必要なログインIDとパスワードを受け付けるフォームをビューに用意します。
ブログ主の場合は何度も使いまわせるように部分テンプレートとして作りました。
ログイン中のユーザーを取得する
class ApplicationController < ActionController::Base
private def current_user
if session[:user_id]
User.find_by(id:session[:user_id])
end
end
(省略)
「ログインしているか」と「誰かログインしているか」を取得できるcurrent_userメソッドを作ります。
application_controllerに記述すれば全てのコントローラーで使えますね。
ログイン中のユーザを表示する
<%if current_user%>
<%="#{current_user.name}さん"%>
<%=link_to("ログアウト",:login,method: :delete,data:{confirm:"本当にログアウトしますか?"})%>
<%end%>
ログインしている場合に、ログインユーザー名とログアウトボタンを表示してあげます。
結果
適切なログインIDとパスワードを入力すると…
無事ログインできましたね(›´ω`‹ )。
くるみ
エラーが出た際の対処法
irb(main):001:0> User.all
You don't have bcrypt installed in your application. Please add it to your Gemfile and run bundle install
Traceback (most recent call last):
3: from (irb):1
2: from app/models/user.rb:1:in `<main>'
1: from app/models/user.rb:2:in `<class:User>'
LoadError (cannot load such file -- bcrypt)
途中でこのようなエラーが出た場合は以下の記事に対処法をまとめたのでご覧ください。

まとめ
参考になれば幸いです!では⸝⸝- ̫ -⸝⸝