Rails sorcery
やりたいこと
sorceryについて理解を深めたかったので、GitHubを参照し、Wiki等に記載されている内容をまとめます。 実装方法については深く解説していないで、詳しく知りたい方はsorceryのGitHubを参照してください
Userモデルを作成する
bundle exec rails g sorcery:install
class SorceryCore < ActiveRecord::Migration[6.0] 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
crypted_password
暗号化されたパスワード(crypted_password)。試しにrails consoleでユーザーを作成して、Userテーブルのcrypted_passwordを見てみるとめちゃ長い文字列になっている。
一方,users テーブルには password や password_confirmation というカラムは無い,ということも分かります。
password を暗号化した文字列を作成して crypted_passoword カラムに収めるのは sorcery が自動的にやってくれます。
パスワードが保存される過程は、 以下のように、「仮想的な」passwordフィールドを使用し、データベースに暗号化される前のパスワードをビューで扱う。 →このpassword属性はカラムに対応していないため、平文のパスワード情報がDBに保存されることは無い。 →パスワードは暗号化され、DBに保存される。
modelに記載されている内容
authenticates_with_sorcery! validates :password, length: { minimum: 8 }, 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 :password, confirmation: trueはpasswordというDBに存在しない仮想的な属性(virtual attributes)が追加される。
if: -> { new_record? || changes[:crypted_password] }はユーザーがパスワード以外のプロフィール項目を更新したい場合に、パスワードの入力を省略できるようになる。
Controllerの内容
ログインページのcontorollerを参照しています。
user_sessions_controller.rb
class UserSessionsController < ApplicationController skip_before_action :require_login, only: %i[new create] def new; end def create @user = login(params[:email], params[:password]) if @user redirect_back_or_to(root_path, notice: 'Login success') else render :new end end def destroy logout redirect_to(login_path, notice: 'ログアウトしました') end end
redirect_back_or_to
githubで詳細を見てみると
def redirect_back_or_to(url, flash_hash = {}) redirect_to(session[:return_to_url] || url, flash: flash_hash) session[:return_to_url] = nil end
sessionのreturn to urlがなければこのurlになるみたいなメソッドが書かれている。
例えば、掲示板ページにアクセスしようとしたユーザにログインを要求する場合、require_loginメソッドでユーザをログインページに誘導し、ログインが成功したら、最初に訪れようとしていた掲示板ページにリダイレクトさせるということが可能になる。