search
LoginSignup
0

More than 1 year has passed since last update.

posted at

railsでログイン機能実装

はじめに

前回に引き続いての投稿です!
今回は、ログイン機能の実装についてまとめます!!

目次

  1. Userモデルを作成
  2. gemを導入
  3. user.rbに追記
  4. ログイン機能実装
  5. ログイン情報を取得
  6. ログアウト機能実装
  7. ログインしてない場合の処理
  8. 参考文献

Userモデルを作成

まずUserモデルを作成します。

rails g model User name:string email:string password_digest: string

こちらを実行し、rails db:migrateしてください。
password_digestというのは、Rails標準機能のhas_secure_passwordを使用する際の命名規則となります。

gemを導入

先程作成したpassword_digestには、入力されたパスワードを不可逆にハッシュ化したものが入ります。passwordをそのままDBに保存すると、流出した際に大変危険ですので、このようにすることで漏洩対策となります。
そこで、ハッシュ関数を提供する「bcrypt」というgemを導入します。

gem 'bcrypt', '~> 3.1.7'

gemfileに追記したら、bundle installします。

user.rbに追記

gem導入後、やることは一つだけ。以下を追記します。

User.rb
has_secure_password

これでした準備が完了です!次に、controllerを実装していきます。

ログイン機能実装

ログイン機能は、session[:user_id]というセッションにユーザーのidを保持することで、実現します。
まず、sessions_controller.rbを、ログイン用のnewメソッドと共に作成します。

rails g controller Sessions new 

このnewアクションがログイン画面への遷移となります。今回は、以下のようなフォームにしました。

h1 ログイン

= form_with scope: :session, local: true do |f|
  .form-group
    = f.label :email, 'メールアドレス'
    = f.text_field :email, class: 'form-control', id: 'session_email'
  .form-group
    = f.label :password, 'パスワード'
    = f.password_field :password, class: 'form-control', id: 'session_password'
  = f.submit 'ログインする', class: 'btn btn-primary'


送られてくるパラメータをもとに、ログイン処理を行います。
まずは、routesの編集です。

config/routes.rb
  get '/login', to: 'sessions#new'
  post '/login', to: 'sessions#create' //こちらを追加
controllers/sessions_controller.rb

  def create
    // users テーブルから、一致するメールアドレスが存在するか検索します。
    user = User.find_by(email: session_params[:email])
    // メールアドレスが存在した場合は、パスワードの認証をauthenticateメソッドで行います。
    if user&.authenticate(session_params[:password])
      // 認証に成功したら、sessionuseridを保持します。
      session[:user_id] = user.id
      redirect_to root_url, notice: 'ログインしました。'
    else
      render :new
    end
  end

  private
  def session_params
    params.require(:session).permit(:email, :password)
  end

ログイン情報を取得

以下のコードで、ユーザの情報を取得できます。

User.find_by(id: session[:user_id])

しかし、毎回この記述をするのは面倒なので、application.rbにcurrent_userという変数を定義し、どのcontrollerからでも利用できるようにします。また、helper_methodを指定し、viewでも使えるように書きます!

controllers/application.rb
  helper_method :current_user

  private
  def current_user
    // session[:user_id]に値があれば(ログインしていれば)、@current_userにログインユーザーの情報を格納する
    @current_user ||= User.find_by(id: session[:user_id]) if session[:user_id]
  end

ログアウト機能実装

ログアウト機能は、session[:user_id]を削除することで実現します。

routes.rb
delete 'logout', to: 'session#destroy'
session_controller.rb
  def destroy
    reset_session
    redirect_to root_url, notice: 'ログアウトしました'
  end

viewは以下のようになります

application.html.slim
- if current_user
  li.nav-item= link_to 'ログアウト', logout_path, method: :delete, class: 'nav-link'
- else
  li.nav-item= link_to 'ログイン', login_path, class: 'nav-link'

ログインしてない場合の処理

ログインしなければすべての機能を使えなくする場合は、application_controllerにメソッドを追加します。

application.rb
before_action :login_required

  private
  def login_required
    // current_usernil(ログインしていない)とき、ログイン画面にredirectさせる
    redirect_to login_url unless current_user
  end

上記の記述の場合、ログイン画面もログインしないと見られないというカオスな状況になります。
そこで、session_controllerだけはこの制約を解除します。

session_controller.rb
  skip_before_action :login_required

参考文献

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0