LoginSignup
0
0

More than 3 years have passed since last update.

sorceryで認証機能を追加してみる

Last updated at Posted at 2021-04-06

Sorceryとは?

Sorceryは、ユーザ認証機能を簡単に実装できるライブラリ

パスワード認証機能

今回は基本的な機能であるパスワード認証の実装
・ユーザー登録機能
・ログイン機能
・ログアウト機能

Sorceryの導入

gem 'sorcery'

Userモデルを作成

bundle exec rails g sorcery:installを実行し、Userモデルとデータベースのmigrationを生成します。

今回usersテーブルにはfull_nameカラムを追加そしてstring型と必須項目を追加。
Image from Gyazo

User登録機能を実装

Userモデルをベースに実装していきます。
モデルの実装
はじめに、Userモデルのフィールドである、

・email
・password
・password_confirmation
・full_name
に対するバリデーションを実装します。

class User < ActiveRecord::Base
  authenticates_with_sorcery!

  validates :password, length: { minimum: 3 }, if: -> { new_record? || changes[:crypted_password] }
  validates :password, confirmation: true, if: -> { new_record? || changes[:crypted_password] }
  validates :password_confirmation, presence: true, if: -> { new_record? || changes[:crypted_password] }

  validates :email, uniqueness: true, precense: true
  validates :full_name, presence: true
end

コントローラーの実装

bundle exec rails g controller new createを実行
次にルーティングを定義しておきます。

routes.rb
Rails.application.routes.draw do
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
  resources :users, only: [:new, :create]
end

コントローラーの中身はこの様な感じです

users_controller.rb
class UsersController < ApplicationController
  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to welcome_path #createアクションでUser登録が成功した際にリダイレクト先としてwelcome_pathを指定しています
    else
      render :new
    end
  end

  private

  def user_params #createで送られてきた値をparams.require
    params.require(:user).permit(
      :email,
      :password,
      :password_confirmation,
      :full_name
    )
  end
end

welcome_pathはログイン画面へのパスのためこのままだとroutingエラーになるので後ほどログイン画面へのルーティングを記述します。

Viewの実装

Form_withを使用します。
Bootstrapを使用。

new.html.erb
<div class="container">
   <div class="row">
     <div class="col-md-10 offset-md-1 col-lg-8 offset-lg-2">
       <h1>ユーザー登録</h1>
       <%= form_with model: @user, local: true do |f| %>
         <div class= "form-group">
            <%=f.label :full_name %> 
           <%= f.last_name :full_name, class: form-control %>
         </div>
         <div class="form-group">
           <%= f.label :email %>
           <%= f.email_field :email, class: 'form-control' %>
         </div>
         <div class="form-group">
           <%= f.label :password %>
           <%= f.password_field :password, class: 'form-control' %>
         </div>
         <div class="form-group">
           <%= f.label :password_confirmation %>
           <%= f.password_field :password_confirmation, class: 'form-control' %>
         </div>
         <%= f.submit '登録', class: 'btn btn-primary' %>
       <% end %>
       <div class='text-center'>
         <%= link_to 'ログインページへ', login_path %>
       </div>
     </div>
   </div>

form_withでつまづく可能性があるので参考になるサイトを載せます。

ログイン画面へのルーティング

ログイン画面はSessionControllerというコントローラーを作成しなければいけません?

$bundle exec rails g controller session new create destroy
routes.rb
get 'welcome', to: 'session#new'
post 'login', to: 'session#create'
logout 'logout', to: 'session#destory'

これでwelcome_pathへるぱが作成され、ログイン画面へのルーティングが可能となりユーザ登録機能が実装できました。
しかし、ここまでの実装ではsorceryの提供する機能は使っていません。
次からsorceryを使った認証機能を実装していきます。

認証機能を実装

ここでは、次のようなシナリオを考えてみます。

認証が必要なページへアクセスした場合
・認証済みの場合
要求されたページを応答する。
・認証されていない場合
ログインページを応答する。
・認証が不要なページへアクセスした場合
要求されたページを応答する。

これを実装するにはルーティングに認証が必要となるページへルーティングを追加します。HomeControllerのindexアクションが該当するものとして、このコントローラをbundle exec rails g controller home indexを実行して作成します。また、home#indexをルートパスとして定義するため、config/routes.rbに以下を追加します

root to: 'home#index'

この時点では認証なしでどこのページでもアクセスできる状態です。

認証済み判定処理

認証が必要なページがリクエストされた場合、認証済みか否かを判定する必要があります。 これを実現するには、Sorceryが提供するrequire_loginメソッドをbefore_actionに指定します。 これは、ApplicationControllerに書きます。 また、require_loginをbefore_actionに指定するにあたり、認証されていない場合の処理も合わせて実装する必要があります。 デフォルトでは、Sorceryは、not_authenticatedというメソッドを実行するため、この名前で実装します。ここでは、認証されていない場合は、ログインページへリダイレクトする実装としています。

application_controller.rb
before_action :require_login

protected

def not_authenticated 
  redirect_to welcome_path
end

ですがこのままではログインページ自体もbefore_actionが動作してしまうため認証済み判定が不必要なControllerではbefore_actionをスキップする必要があります。例えば以下のコードはSession_controllerの実装です

session_controller.rb
skip_before_action :reqire_login, except: [:destroy]
0
0
2

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
  3. You can use dark theme
What you can do with signing up
0
0