無限ループを考案する :require_no_authentication としてフィルター チェーンが停止する
概要
Ruby on Rails 6 と Devise を使用していると奇妙な問題が発生します。サインインまたはサインアウト後、アプリは root_path にリダイレクトされず、無限ループになります。 root_path は認証を必要としないため、リダイレクトすべきではありません。
エラーログ:
ルート:
devise_for :users,
path: "utilisateurs",
controllers: {
sessions: 'users/sessions',
registrations: 'users/registrations',
passwords: 'users/passwords',
confirmations: 'users/confirmations'
},
:path_names => { :sign_in => 'connexion', :sign_up => 'inscription', :sign_out => 'deconnexion', password: 'retrouver_mot_de_passe', edit: 'finaliser-inscription' }
ユーザーモデル:
class User < ApplicationRecord
attr_accessor :skip_password_validation
before_validation :check_pseudo, only: [:create, :update]
validates :pseudo, presence: true
validates :email,
format: { with: URI::MailTo::EMAIL_REGEXP },
presence: true,
uniqueness: true
has_secure_token
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, :confirmable, :trackable
has_many :comments, dependent: :nullify
has_one :author, dependent: :nullify
has_one :blitz_score, :dependent => :destroy
has_one :blitz_conjugaison_score, :dependent => :destroy
has_many :quiz_scores, :dependent => :destroy
has_many :dictee_scores, :dependent => :destroy
has_many :crossword_scores, :dependent => :destroy
has_many :track_subscribers, :dependent => :destroy
def authenticatable_salt
return super unless session_token
"#{super}#{session_token}"
end
def invalidate_all_sessions!
update_attribute(:session_token, SecureRandom.hex)
end
protected
def check_pseudo
unless self.pseudo.present?
self.pseudo = self.email.split("@")[0] if self.email.present?
end
end
def password_required?
return false if skip_password_validation
super
end
end
アカウントの作成にパスワードは必要ないことに注意してください。訪問者は最初にメールアドレスを入力し、アカウントを確認した後に擬似パスワードとパスワードを入力します。
セッションコントローラー:
class Users::SessionsController < Devise::SessionsController
layout 'blank'
protected
def after_sign_in_path_for(resource_or_scope)
root_path
end
def after_sign_out_path_for(resource_or_scope)
root_path
end
end
イニシャライザを考案します:
Devise.setup do |config|
require 'devise/orm/active_record'
config.case_insensitive_keys = [:email]
config.strip_whitespace_keys = [:email]
config.skip_session_storage = [:http_auth]
config.stretches = Rails.env.test? ? 1 : 12
config.reconfirmable = false
config.expire_all_remember_me_on_sign_out = true
config.password_length = 6..128
config.email_regexp = /\A[^@\s]+@[^@\s]+\z/
config.reset_password_within = 24.hours
config.navigational_formats = ['*/*', :html]
config.sign_out_via = :delete
end
開発構成:
Rails.application.configure do
config.cache_classes = false
config.eager_load = false
config.consider_all_requests_local = true
if Rails.root.join('tmp', 'caching-dev.txt').exist?
config.action_controller.perform_caching = false
config.action_controller.enable_fragment_cache_logging = true
config.cache_store = :memory_store
config.public_file_server.headers = {
'Cache-Control' => "public, max-age=#{2.days.to_i}"
}
else
config.action_controller.perform_caching = false
config.cache_store = :null_store
end
config.active_storage.service = :local
config.action_mailer.raise_delivery_errors = false
config.action_mailer.perform_caching = false
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
config.action_mailer.delivery_method = :mailjet
config.active_support.deprecation = :log
config.active_record.migration_error = :page_load
config.active_record.verbose_query_logs = true
config.assets.debug = true
config.assets.quiet = true
config.file_watcher = ActiveSupport::EventedFileUpdateChecker
config.active_job.queue_adapter = :sidekiq
config.i18n.default_locale = :fr
config.after_initialize do
Bullet.enable = true
Bullet.bullet_logger = true
Bullet.unused_eager_loading_enable = false
Bullet.raise = false
end
end
次のことを試しましたが成功しませんでした。
これが問題の原因であるかどうかはわかりませんが、他のいくつかの Rails アプリに取り組んでいます。 Rails を使用してそれらを個別に起動し、サーバーは localhost:3000 にあります。おそらくこれによりセッションが台無しになる可能性がありますか?
助けてくれてありがとう。
解決策
結局、問題は PWA 実装の service-worker.js に関連していました。
どういうわけか、Devise は service-worker.js にリダイレクトしていたため、無限リダイレクト ループが発生していました。