Sorceryでログイン機能を実装する
こんにちは。りゅうじです。
sorcery
を使うのでまずはインストールします。
インストール
#Gemfile
gem 'sorcery'
#ターミナル
$ bundle install --path vendor/bundle
初期設定
#ターミナル
$ bundle exec rails g sorcery:install
このコマンドで必要最低限のファイルが生成される。
DBに反映
#db/migrate/20xxxxxxx_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.string :first_name, null: false
t.string :last_name, null:false
t.timestamps null: false
end
add_index :users, :email, unique: true
end
end
初期設定のコマンドでこんなマイグレーションファイルが生成されていて
認証に必要最低限のカラムが定義されています。(今回は名前を追記しています)
このように他にもカラムが欲しい場合は自分で追記しましょう。
#ターミナル
$ bundle exec rails db:migrate
モデルにバリデーションを設定
#app/model/user.rb
class User < ApplicationRecord
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
validates :email, presence: true
validates :first_name, presence: true, length: { maximum: 255 }
validates :last_name, presence: true, length: { maximum: 255 }
end
if: -> { new_record? || changes[:crypted_password] }
登録したユーザーがパスワード以外を更新したい場合にパスワードの入力を省略させます。
登録済みなのに名前を更新しようとしたら毎回パスワード書くことになるの嫌ですよね。
routesの設定
#config/routes.rb
root 'static_pages#top'
get 'login', to: 'user_sessions#new'
post 'login', to: 'user_sessions#create'
delete 'logout', to: 'user_sessions#destroy'
resources :users, only: %i[new create]
end
コントローラーの設定
#app/controllers/user_sessions_controller.rb
class UserSessionsController < ApplicationController
def new
end
def create
@user = login(params[:email], params[:password])
if @user
redirect_back_or_to root_path
else
render :new
end
end
def destroy
logout
redirect_to root_path
end
end
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
redirect_to login_path
else
render :new
end
end
private
def user_params
params.require(:user).permit(:email, :password, :password_confirmation, :last_name, :first_name)
end
end
user_sessions_controller
⇨ログイン
users_controller
⇨新規登録
ビューの設定
#app/views/user_sessions/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 url: login_path, local: true do |f| %>
<div class="form-group">
<%= f.label :email %>
<%= f.text_field :email, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
</div>
<div class="actions">
<%= f.submit 'ログイン', class: 'btn btn-primary' %>
</div>
<% end %>
<div class='text-center'>
<%= link_to '登録ページへ', new_user_path %>
<a href="#">パスワードをお忘れの方はこちら</a>
</div>
</div>
</div>
</div>
#app/views/users/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 :last_name %>
<%= f.text_field :last_name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :first_name %>
<%= f.text_field :first_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>
</div>
user_sessions
にはモデルがない
users
モデルがある
この違いからform_with
の後の記述が異なります。
基本的に model:
を使うと覚えておいて
今回のログインに使うuser_sessions
のような場合は url:
になります。
またi18n
での日本語訳の場合、model:
ならば自動で翻訳してくれます。url:
の場合は自分でlavel
に追記する必要がある事を覚えておいて下さい。
i18n
がわからない方はこちらの過去記事をどうぞ。
https://ryujisurf55.hatenablog.com/entry/2021/04/24/211738
sorcery
で使えるようになるメソッドがあるので、Coreのものだけを次回の記事にしてみます。
最後に
読んでいただいた方、ありがとうございました。