I have a weird issue using Ruby on Rails 6 and Devise. After signing in or signing out, the app is on an infinite loop instead of redirecting to the root_path. The root_path does not require any authentication so it shouldn't redirect.
Error logs:
Started POST "/utilisateurs/connexion" for ::1 at 2023-12-27 10:22:42 +0100 Processing by Users::SessionsController#create as HTML Parameters: {"authenticity_token"=>"[FILTERED]", "user"=>{"email"=>"email@email.fr", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Je me connecte"} User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 55786], ["LIMIT", 1]] after_sign_in_path_for Redirected to http://localhost:3000/ Filter chain halted as :require_no_authentication rendered or redirected
Completed 302 Found in 3ms (ActiveRecord: 0.2ms | Allocations: 1911)
Started GET "/utilisateurs/" for ::1 at 2023-12-27 10:22:42 +0100
Routes:
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' }
User model:
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
Note that I don't require the password to create an account. Visitors give their email first, then they can fill in their pseudo
and password
after they confirm their account.
Sessions controller:
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 initializer:
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
Development config:
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
I tried the following without success:
skip_password_validation
in User modelNot sure if this could be the origin of the issue, but I am working on several other rails apps. I fire them separately using rails s
and the server is on localhost:3000. Maybe this could mess up with the sessions or else?
Thank you for your help.
In the end, the issue was related to the service-worker.js of the PWA implementation.
Somehow, Devise was redirecting to the service-worker.js, resulting in an infinite redirect loop.