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