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も利用してみてください!

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

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

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