環境
ruby "3.2.2"
rails "7.0.7"
Docker
Gemのインストール
【Gemのインストール】
Gemfileに以下を記述し、ターミナルでbundle installします。
Dockerを使用している場合の注意点
Dockerを使用している場合はコンテナ内に入ってから記述します。コンテナの外にいる状態で記述した場合、コンテナに入れなくなる場合があります。その場合は一旦削除してコンテナに入り再び記述し直してください。
gem 'sorcery'
bundle install
*インストールもDocker内で行います。
ターミナルで次のコマンドを実行して、コア移行ファイル、初期化ファイル、および User
モデル クラスを生成します。
rails generate sorcery:install
以下のファイルが作成されます。
app/models/user.rb
config/initializers/sorcery.rb
db/migrate/202◯◯◯◯◯◯◯◯◯◯_sorcery_core.rb
spec/factories/users.rb
spec/models/user_spec.rb
【マイグレーションファイルの確認】
class SorceryCore < ActiveRecord::Migration[6.1]
def change
create_table :User do |t|
t.string :email, null: false, index: { unique: true }
t.string :crypted_password
t.string :salt
t.timestamps null: false
end
add_index :User, :email, unique: true
end
end
sorceryの基本のUserテーブルが作成されています。
カラムはemailとpasswordです。crypted_
とsalt
はパスワードをハッシュ化するためのものです。
emailはnull: false
で入力必須、index: { unique: true }
で同じアドレスが登録できないバリデーションがかけられています。
もしUserテーブルにnameカラムを作成したい場合はここで記述します。
t.string :email, null: false, index: { unique: true }
t.string :crypted_password
t.string :salt
t.string "first_name", null: false
t.string "last_name", null: false
確認後、ターミナルでdb:migrateします。
rails db:migrate
sorcery基本のログイン編
【Userモデルを作成】
class User < ApplicationRecord
authenticates_with_sorcery!
end
authenticates_with_sorcery! は、Userモデルにsorceryによる認証機能を持たせています。
この下にバリデーションを記述していきましょう。
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, presence: true, uniqueness: true
validates :reset_password_token, presence: true, uniqueness: true, allow_nil: true
【コントローラーを作成】
rails g controller user_sessions
以下のファイルが作成されます。
app/controllers/user_sessions_controller.rb
app/views/user_sessions
test/controllers/user_sessions_controller_test.rb
app/helpers/user_sessions_helper.rb
controllerの中身を作成しましょう。こちらが超基本のかたちです。
公式参考ページ
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
名前 | 説明 |
---|---|
login | (params[:email], params[:password])でformに入力されたemailとpasswordの値を受け取ります。 emailによるUser検索、パスワードの検証を行い、正常に処理できるとセッションデータにUserレコードのid値を格納する、という処理が行われています。 |
logout | loginセッションをリセットします。 |
redirect_back_or_to | 未ログイン時アクセス不可のページを開こうとした際、require_loginメソッドでユーザをログインページに誘導し、ログインが成功したら、最初に訪れようとしていたページにリダイレクトさせるということが可能になります。 |
【ルーティングの編集】
get 'login', to: 'user_sessions#new'
post 'login', to: 'user_sessions#create'
delete 'logout', to: 'user_sessions#destroy'
これでlogin_path、logout_pathが使えるようになります。
生成されたpathを確認してみましょう。
http://localhost:3000/rails/info/routes
【ビューの作成】
ログインフォーム
<%= form_with url: login_path do |f| %>
<%= f.label :email %>
<%= f.email_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.submit "ログイン" %>
<% end %>
fieldに入力された値をuser_sessions_controllerのcreateで受け取ります。
sorceryの便利なメソッド
【logged_in?】
ログインしているかの有無で表示を変えたり処理を変えたりすることができます。
例えば、ログインしていなければログインリンクのついたヘッダーを、ログインしていればメニューが表示されるヘッダーを等切り替えることができます。
<body>
<% if logged_in? %> # ログインしていたら
<%= render 'shared/header' %> # こっちを表示
<% else %> # してなかったら
<%= render 'shared/before_login_header' %> # こっちを表示
<% end %>
<%= render partial:"shared/flash_message" %>
<%= yield %>
<%= render 'shared/footer' %>
</body>
【require_login】
未ログイン状態で表示させられるページを制限できます。
class ApplicationController < ActionController::Base
before_action :require_login
end
application_controllerでbefore_action :require_loginを記述するとすべてのコントローラーに対して適応されます。つまりこの状態だと、すべての画面がログインしていないとアクセスできなくなります。
class UserSessionsController < ApplicationController
skip_before_action :require_login, only: [:new, :create]
end
ログインを必要としないページのアクションをskip指定し、require_loginを回避します。
一般的にHome、Top画面に指定したページと、ユーザー登録、ログイン画面等、ログイン前に訪れるページはrequire_loginを回避します。
【not_authenticated】
ログインしていない場合に呼ばれるメソッドです。
『ログインしていなかったらフラッシュメッセージを表示する』『ログインしていなかったらこのページにリダイレクトをする』などの処理を記述します。
private
def not_authenticated
redirect_to login_path
flash[:danger] = 'ログインしてください'
end
参考サイト
関連記事