问题
I'm using Devise for authentication in my rails app and I'd like to be able to block certain accounts and prevent users from reregistering with a blocked email. I'm just not sure what the best way is to go about it.
My first thought was to override the sessions and registrations controllers to check the model for a user with a blocked bit, but I have a feeling there might be a more elegant way.
回答1:
I would do it like this:
def after_sign_in_path_for(resource)
if resource.is_a?(User) && resource.banned?
sign_out resource
banned_user_path
else
super
end
end
回答2:
The best approach is to do it in Devise way:
Below assumes that you are using Devise database_authenticatable module and your application's users model names User.
1. Implement an account_active? method.
Add boolean account_active
column in users table or define account_active?
method in User model (you can chose your own method name). For example:
# app/models/user.rb
def account_active?
blocked_at.nil?
end
2. Overwrite the active_for_authentication?
method in your model (User).
# app/models/user.rb
def active_for_authentication?
super && account_active?
end
3. Add method which returns translation for flash message.
Whenever active_for_authentication?
returns false, Devise asks the reason why your model is inactive using the inactive_message
method.
# app/models/user.rb
def inactive_message
account_active? ? super : :locked
end
And that's it. You don't need to care about sign_out
or redirect_to
user.
Moreover, user is locked immediately, with next request, not after next sign in.
More: devise/authenticatable.rb.
回答3:
A better solution is to override the active_for_authentication? method on the devise model (User). Like so:
def active_for_authentication?
super && !self.banned?
end
回答4:
A more elegant approach is to override the (User) controller's find_for_authentication method, scoping it for only unblocked users. That way, trying to log in as a blocked user is like trying to log in as a user who doesn't exist. (If you want to tell the user she's blocked, you could set a flash alert here too. Here's a good run-through.
回答5:
You could create a custom validation method in the User model, which, on create, checks whether the email is on the blocked list of emails.
来源:https://stackoverflow.com/questions/3894919/what-is-the-best-way-to-ban-block-users-with-devise-for-rails