Devise authentication without password, using just username
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.
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.
This can definitely be done using sign_in by including Devise::Controllers::Helpers
if you're not already inheriting from a DeviseController
or a controller that inherits from DeviseController
(such as Devise::SessionsController
). Then just call sign_in(user)
:
class SignInWithoutPasswordsController < ApplicationController
include Devise::Controllers::Helpers
def sign_a_user_in_without_password
user = User.find(params[:user_id])
sign_in(user)
end
end