Devise authentication without password, using just

2019-01-23 07:16发布

问题:

Is it possible to set up Devise to authenticate without a password?

This is an intranet app. In order to connect to it, you would have to be on the VPN in the first place, plus the app only allows to see the status of orders & history, not submit any information. I guess similar to FedEx or UPS tracking website but allows to user to see the whole account, with an added security of a VPN box the client get from us.

Now I would still require a password, but this is a non-negotiable requirement on the project. Clients are used to this scheme and are not very computer savvy to adjust to a change quickly.

回答1:

The not-so-elegant solution (that doesn't require Devise modification): use a default password that is identical for all users

Use a before_validation callback to set user.password and user.password_confirmation to a default value (e.g. password).

Generate the Devise views with rails generate devise:views

Modify sign in form to add a hidden password field with your default password value.

As I said, not elegant, but it should do the trick without needing to dig inside Devise internals.


More elegant solution:

Fork the Devise project on GitHub and adapt https://github.com/plataformatec/devise/blob/master/lib/devise/strategies/database_authenticatable.rb to your needs

You can then specify your fork in the Gemfile.



回答2:

In this instance, I prefer to monkey-patch Devise::Strategies::Authenticatable instead of forking the whole devise repository to make a one line change.

Devise::Strategies::Authenticatable.class_eval do
  private
    def valid_password?
      true
    end
end

Just place it in an initializer file or at the end of the devise.rb initializer (I prefer this because it seems a bit like an additional devise configuration).

To explain, the valid_password? patched here usually just returns password.present? and is used by Devise::Strategies::DatabaseAuthenticatable as an initial validation of the password before actually checking it against the database. Therefore this will only change the behaviour when the password is not provided.

DISCLAIMER: This works so far for me, but is not fully tested so use at your own risk.