自定义Devise SessionsController创建动作

时间:2018-12-19 15:09:41

标签: ruby-on-rails devise passwords

我想添加一项功能,该功能会将密码过期的用户重定向到“重置密码”页面。 我的控制器看起来像这样

class Users::SessionsController < Devise::SessionsController

  def create
    user = User.find_by(email: params[:user][:email].downcase)
    if user.password_expire?
      raw, enc = Devise.token_generator.generate(current_user.class,
                                               :reset_password_token)
      user.reset_password_token   = enc
      user.reset_password_sent_at = Time.now.utc
      user.save(validate: false)
      redirect_to edit_password_url(user, reset_password_token: raw)
    else
      self.resource = warden.authenticate!(auth_options)
      set_flash_message(:notice, :signed_in)
      sign_in(resource_name, resource)
      yield resource if block_given?
      respond_with resource, location: after_sign_in_path_for(resource)
    end
  end

end

当我在操作顶部使用binding.pry进行调试时,我发现current_user存在并且user_signed_in吗?是真的。在create方法完成之前,我怎么可能登录?

2 个答案:

答案 0 :(得分:2)

如果您正在使用安全扩展,则根本不需要照顾密码过期的实现。 如果您不使用它,则应将其检出-devise_security_extension

答案 1 :(得分:1)

Devise会记住当前使用Cookie的用户,直到他们注销为止。

仅仅因为他们点击了您的登录路线并不意味着他们已经退出。

潜入设计

在Devise中跟踪代码以了解会发生什么:

1。 Devise::SessionsController#create

class Devise::SessionsController < ApplicationController
  # ...
  def create
    # ...
    sign_in(resource_name, resource)
    # ...
  end
end

2。 Devise::Controllers::Helpers#sign_in

  def sign_in(resource_or_scope, *args)
    # ...
    if options[:bypass]
      warden.session_serializer.store(resource, scope)
    elsif warden.user(scope) == resource && !options.delete(:force)
      # Do nothing. User already signed in and we are not forcing it.
      true # <=== Here's the moment of truth
    else
    # ...
  end

结论

  • 用户已经登录后可以点击您的sessions#create
  • 在这种情况下,默认的Devise行为是什么也不做
  • 不太确定您要实现的目标,但是在某些地方调用super可能会很方便,以恢复默认的Devise行为