Reputation: 708
I want to lock the user after 5 multiple attempts in my application. So it is working when i use devise lockable. But i want to use it for API method except default action.
devise :database_authenticatable, :registerable, :lockable
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
post '/user_sign_in' => 'api/users#user_sign_in'
if i am using api call 'user_sign_in' method. It is not updating devise lockable method. How to trigger devise method in API?
Upvotes: 1
Views: 1343
Reputation: 1314
To increment lock count you would use user.increment_failed_attempts
. However, to see whether the user is locked or not you would use user.access_locked?
.
The sample code is here:
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
Upvotes: 1
Reputation: 708
I have added /lib/devise/models/lockable.rb files in my application. i have used the below methods based on my lockable functionalities. It is working fine.
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
Upvotes: 1
Reputation: 164
#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
Upvotes: 2