Programming Journal

学習したことの整理用です。

【Rails】【devise】deviseを使って認証機能を実装する

実装したいこと

ログイン機能・ユーザーの新規作成機能を実装したい。
sorceryは使ったことがあったのですが、試しにdeviseでも認証機能を作成したいと思います。
とりあえず、必要最低限な部分は結構簡単にできました。

実装の流れ

  • gem 'devise'のインストール
  • Model生成
  • View生成
  • Controller生成
  • Routing編集

gem 'devise' インストール

公式に沿ってインストールしていきます。
Starting with Rails?のところから
GitHub - heartcombo/devise: Flexible authentication solution for Rails with Warden.

gem 'devise'

ターミナルでbundle installします。

generatorを走らせます。

$ rails generate devise:install

Model

Userモデルを作ります。

$ rails generate devise User

$ rails db:migrate

View

ビューファイルも勝手に作られますが、とても簡素なので、カスタムしていくために生成します。

$ rails generate devise:views users

Controller

コントローラーもカスタムしたいので、生成します。

rails g devise:controllers users 

このコマンドを実行すると、一連のコントローラーが自動生成されます。(ログイン用、新規登録用などなど…

f:id:Study-Diary:20201013172308p:plain
rails g devise:controllers users

とりあえず、ログイン・ログアウト機能に必要な部分のコメントアウトを外してあげる。

# frozen_string_literal: true

module Users
  class SessionsController < Devise::SessionsController
    # before_action :configure_sign_in_params, only: [:create]

    def new
      super
    end

    def create
      super
    end

    def destroy
      super
    end

    # protected

    # If you have extra params to permit, append them to the sanitizer.
    # def configure_sign_in_params
    #   devise_parameter_sanitizer.permit(:sign_in, keys: [:attribute])
    # end
  end
end

Routing

さっき、作成したコントローラーを使うことをルーティングファイルに知らせます。

Rails.application.routes.draw do
  devise_for :users, controllers: {
    registrations: 'users/registrations',
    sessions: 'users/sessions'
  }

  devise_scope :user do
    get '/users/sign_in', to: 'users/sessions#new'
    get '/users/sign_out', to: 'users/sessions#destroy'
  end
end

私はこの設定を誤ってエラーを起こしました。

rails routesで全体のルーティングを確かめるとこんな感じです。

f:id:Study-Diary:20201013173354p:plain
rails routes

View諸々の編集

ログイン前と後でヘッダーの表示を変える設定
flash.noticeを表示させるところの設定など…

(略)
body
    -if user_signed_in? #signed_in?はdeviseで用意されてるメソッド
      = render 'shared/header'
    -else
      = render 'shared/before_login_header'
    -if flash.notice.present?
      .alert.alert-success= flash.notice
    = yield
    = render 'shared/footer'

ログイン前のヘッダー。ログイン用のリンクなど…

ログイン後のヘッダー。ログアウト用のリンクなど…

(略)
  #navbarSupportedContent.collapse.navbar-collapse
     ul.navbar-nav.ml-auto
      li.nav-item.active = link_to 'Logout', users_sign_out_path, method: :delete, class: 'nav-link'

これがデフォルトのログイン画面

f:id:Study-Diary:20201013174321p:plain
ログイン画面

Application_controller

ログインしていない場合は、ログインページにリダイレクトさせる。
このフィルターをかけたくないコントローラーには、skip_before_action :authenticate_user!を記入しておく。

class ApplicationController < ActionController::Base
  before_action :authenticate_user!
end

翻訳ファイル

GitHub - Junsuke/miscellaneous: convenient files for later use

参考

Rails Girls - Japanese

【Rails】deviseの使い方をマスターしてログイン認証機能を実装 | Pikawaka - ピカ1わかりやすいプログラミング用語サイト

Deviseの設定手順をまとめてみた。 その2 ViewとControllerのカスタマイズ編 - Qiita