【问题标题】:How to use Devise lockable functionality outside of devise controller or method?如何在设计控制器或方法之外使用设计可锁定功能?
【发布时间】:2019-07-11 20:51:15
【问题描述】:

我想在我的应用程序中多次尝试后锁定用户。所以当我使用可锁定的设计时它正在工作。但我想将它用于 API 方法,默认操作除外。

当我使用设计控制器和模型时,它正在工作

设计 :database_authenticable, :registerable, :lockable

我的控制器中的user_sign_in方法#使用自己的方法在我的控制器中不起作用

  if user.first.valid_password?(params[:password])
    user.update_attributes(current_sign_in_at: DateTime.current)

    success_response(:ok, user, message: 'success message')
  else

    error_response(412, nil, 'failure message')
  end

在路线中

发布'/user_sign_in' => 'api/users#user_sign_in'

如果我使用 api 调用“user_sign_in”方法。它不是更新设计可锁定方法。如何在 API 中触发设计方法?

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    要增加锁计数,您可以使用user.increment_failed_attempts。但是,要查看用户是否被锁定,您可以使用user.access_locked?。 示例代码在这里:

    if user.access_locked?
      return redirect_to root_path, alert: 'Your account is locked'
    end
    
    unless user.valid_password?(params[:password])
     if Devise.maximum_attempts <= user.increment_failed_attempts
       user.lock_access!(send_instructions: true)
     end
     user.save(validate: false)  
    end 
    

    【讨论】:

    • 感谢您的回答。我会试试这个选项
    【解决方案2】:
    #You Can Try this way. It will work Perfectly
    
    if user.failed_attempts >= Devise.maximum_attempts
                user.lock_access!(send_instructions: true)
        else
                user.increment_failed_attempts
    end
    

    【讨论】:

      【解决方案3】:

      我在我的应用程序中添加了 /lib/devise/models/lockable.rb 文件。我根据我的可锁定功能使用了以下方法。它工作正常。

      def lock_access!(opts = { })
          self.locked_at = Time.now.utc
          if unlock_strategy_enabled?(:email) && opts.fetch(:send_instructions, true)
            send_unlock_instructions
          else
            save(validate: false)
          end
        end
      
      
       def send_unlock_instructions
          raw, enc = Devise.token_generator.generate(self.class, :unlock_token)
          self.unlock_token = enc
          save(validate: false)
          send_devise_notification(:unlock_instructions, raw, {})
          raw
        end
      
        def access_locked?
          !!locked_at && !lock_expired?
        end
      
        def increment_failed_attempts
          self.class.increment_counter(:failed_attempts, id)
          reload
        end
      
         def unlock_access_by_token(unlock_token)
            original_token = unlock_token
            unlock_token   = Devise.token_generator.digest(self, :unlock_token, unlock_token)
      
            lockable = find_or_initialize_with_error_by(:unlock_token, unlock_token)
            lockable.unlock_access! if lockable.persisted?
            lockable.unlock_token = original_token
            lockable
          end
      

      【讨论】:

        猜你喜欢
        • 2011-07-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多