文系エンジニア大学生の技術ブログ

社会が多様化していく中、大学生の学生生活も多様であるべきと考えています。主にエンジニア向けにITやプログラミングなどの技術系と大学生向けに休学、留学、海外生活、トビタテ留学、長期インターンに関する記事を書いています。

rails deviseの代わりにSorceryを使って認証機能をしてみたよ

f:id:daikiyano:20190209105149p:plain

今回は、deviseの代わりに認証系gemファイル「Sorcery」を使って認証機能の実装の仕方についてご紹介します。

Sorceryのメリット・デメリット

メリット

  • deviseに比べて重くない
  • カスタマイズしやすい。
  • 自分でコードを書くので、エラーが起きた時に原因を突き止めやすい。

デメリット

  • 情報量が少ない。
  • 1からコードを書かないといけない。

railsの認証系gemで最も有名なのが、「devise」です。deviseを使うと「rails g devise:install」をコマンド上で実行してしまえば 簡単に認証機能を実装することができます。その一方で、自動的に認証機能の実装がされてしまうので、カスタマイズのしにくく、不必要なファイルやコードが存在してしまうというデメリットがあります。 一方のSorceryは必要な機能だけをコードを書き実装することができるので、deviseに比べてライトに認証機能の実装をすることができます。 しかし、deviseに比べてネットの情報量は少なめです。

Gunosyさんも認証機能でSorceryを採用しているとのことです。

tech.gunosy.io

それでは、早速実装してみましょう!

・参照

github.com

Sorceryの導入

1、sorceryを導入します。 gemファイルに記入したらbundle installします。

gem 'sorcery'

2、コマンド上で以下を実行します。

rails g sorcery:install

これで、導入完了です。

導入を終えるとmigrationファイルが生成されるので、確認してみます。

db/migrate/********_sorcery_core.rb
class SorceryCore < ActiveRecord::Migration[5.2]
  def change
    create_table :users do |t|
      t.string :email,            :null => false
      t.string :crypted_password
      t.string :salt

      t.timestamps                :null => false
    end

    add_index :users, :email, unique: true
  end
end

マイグレーションファイルがあることを確かめたらrails db:migrateを実行します。

ユーザー登録の実装

今回は、以下の三つで認証機能の実装を行いたいと思います。

  • email
  • password
  • password_confirmation

app/models/user.rbに上記三つのバリデーションを記入します。

app/models/user.rb


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
end

続いてコマンド上で rails g controller users new create  を実行し、ユーザー登録用ユーザーコントローラーを生成します。 生成したら、usersコントローラーに以下を記載します。

class UsersController < ApplicationController

  def new
    @user = User.new
  end

  def create
  @user = User.new(user_params)
    if @user.save
      redirect_to admin_home_path
    else
      render :new
    end
  end

  private
  def user_params
    params.require(:user).permit(:email,:password,:password_confirmation)
  end
end

続いて、ユーザー登録画面のviewにコードを書いていきます。

app/views/users/new.html.erb

<h1>Sign up</h1>
    <%= form_for(@user) do |f| %>
        <div>
            <%= f.label :email, "Email" %>
            <%= f.email_field :email %>
        </div>
        <div>
            <%= f.label :password,"Password" %>
            <%= f.password_field :password %>
        </div>
        <div>
            <%= f.label :password_confirmation, "password_confirmation" %>
            <%= f.password_field :password_confirmation %>
        </div>

        <%= f.submit "Sign UP" ,class:"btn_send" %>
    <% end %>

f:id:daikiyano:20181027171052p:plain

ログイン機能の実装

続いてログイン機能の実装をするためにrails g controller sessions new create destroyをコマンド上で実行し、 セッションコントローラーを生成します。

生成したら以下をセッションコントーラーに記載。

class SessionsController < ApplicationController
  before_action :require_login, only: [:destroy]
  def new
  end
  # ログイン後の処理 
  # Sorceryのログインメソッドlogin()⇨emailとパスワードの検証を行う。
  def create
    @user = login(params[:email],params[:password])
      if @user
        redirect_to admin_home_path
      else
        render :new
      end
  end

  def destroy
    logout
    redirect_to root_path
  end

  private

  def not_authenticated
    redirect_to root_path
  end

end
  • login() ・・・ emailとパスワードが一致しているかの検証を行う。
  • before_action :require_login ・・・コントローラー上部に記載でログイン中のユーザーのみがアクセス可能に。

not_authenticatedを定義することで、ログインしていないユーザーがアクセスした場合root_pathへリダイレクトするように設定しました。

続いてログイン画面のビュー画面の実装を行います。

app/views/sessions/new.html.erb


<h1>Login</h1>
    <%= form_tag login_path, method: :post do %>
        <div>
           <%= label_tag :email %>
           <%= email_field_tag :email %>
       </div>
       <div>
         <%= label_tag :password %>
         <%= password_field_tag :password %>
      </div>
      <div>
        <%= submit_tag "Login" %>
      </div>

    <% end %>


f:id:daikiyano:20181027171032p:plain

adminページの作成

adminページの作成も行います。

今回は、adminフォルダの配下にhomecontrollerを置きたいので、

rails g controller admin/home indexを実行。

class Admin::HomeController < ApplicationController
    before_action :require_login
    def index
      @user = current_user
    end
end

adminのホーム画面に before_action :require_loginを配置し、ログインしているユーザーのみがアクセス可能にします。

実行したら、adminページのビューの作成します。

<h1>Admin Page</h1>

    <% if current_user %>
        <h1><%= @user.email %></h1>
        <%= form_for(@user,url:logout_path,method:"delete") do |f| %>
          <%= f.submit "Logout", data: { confirm: "Are you sure you logout?"}, class: "btn_send" %>
        <% end %>
    <% end %>
  • if current_user ・・・ログインしているかどうかの真偽値

以上でSorceryの認証機能の実装は完了です。 是非、時間のある方はdeviseだけでなくSorceryも利用してみてください!