Is there a way I can tell Devise not to use a password? I'm using Devise with LDAP so the encrypted password field is a wasted column (the password is stored in the LDAP directory). If I delete the encrypted_password column and then add some dummy accessors on my models
def encrypted_password
""
end
def encrypted_password=dummy
end
I can at least get rid of the column in the database. However, when I create new users I still have to supply a dummy password
User.create(:first_name => "Dummy", :password => "dummyPass1", :password_confirmation => "dummyPass1")
Is there a setting somewhere that would make this cleaner?
You can take "database_authenticatable" out of the devise config line in your User model, and drop the encrypted_password field entirely.
Related
in devise rails gem, what is the difference between these two?
I have seen the :encrypted_password field in the generated schema but not :password field.
Any explanations if these two are interconnected with each other?
Devise::Models::DatabaseAuthenticatable has a setter for that:
def password=(new_password)
#password = new_password
self.encrypted_password = password_digest(#password) if #password.present?
end
So you should set the password as if there was a password field, devise will take care of encrypting it.
As #spickermann already pointed out - plain text password should never be stored anywhere and should filtered out from logs/error messages and so on, because this produces a huge security risk: the encrypted password leak is not totally harmless, but not dangerous that much.
password is the plain text the user set as his password (and plain text password should never be stored anywhere). encrypted_password this the encrypted version of this password.
You might want to read SecurePassword.
:password is the password that a user sets through a form.
:encrypted_password is what is stored in your database and retrieved to create a user session.
Essentially, :encrypted_password is a hashed and salted version of :password that can be safely stored in your database. See this answer if you need more information on why you shouldn't store plain text passwords in your database.
I've a password stored in a database.
The user should be able to set a new one.
I've also used attr_encrypted gem to store it as encrypted text (symmetric because i need it back to connect to other services and not just to login) but this is another story.
When I show the form, the default behavior of ruby helpers is to not send back the password to the browser for obvious security reasons.
Here is the code:
<%= f.input :app_password, :as => :password %>
this behavior might be ok, nevertheless some issues arise from it.
if the user saves the form with null password, the password will be erased. I should test and avoid null-password savings but in some application null password is acceptable and doing so i would prevent this possibility.
it doesn't provide a visual feedback to the user on the fact that he or she has compiled the password field.
it doesn't play very well with validations
What are my options here in order to obtain the most standard possible behavior (that is, no 'change password' checkboxes)?
Please, in forms include password fields this way:
<%= f.password_field :app_password %>
The standard use and set of password is:
Add to your user model a call to has_secure_password
Add field to users for store an encripted password, migration: add_column :users, :auth_token, :string
Before create generate a token:
begin
self.auth_token = SecureRandom.urlsafe_base64
end while User.exists?(auth_token: self.auth_token)
Authenticate your users with #user.authenticate(params[:password])
Update password at another form with 3 fields, old_password, password, and password_confirmation.
I'm using the "has_secure_password" way to store a secure password in the database. When creating an user by the admin (in my app users are created, users can't create an account themselves), in the user model the password_digest is filled by a method to create a random password (see code). When the record is then saved, it is saved secure. So the user method is creating a password_digest say "TY5665^%^", then it is saved in the database say "Y^6&$d%$56GFT". Great!
before_validation :create_random_password, :on => :create
def create_random_password
self.password_digest = SecureRandom.hex(5)
end
But when the new user logs in and changes his password in his profile, the new password gets saved OK, but unsecured! Say the user is changing it to "password1", it also gets saved as "password1" in the database. So why is the secure password working on create, but not on update?
Without seeing your update code, make sure your update is to :password, not :password_digest. The magic behind the creation of a password hash to go into :password_digest only starts with :password.
Surprised that you can save your own password directly onto :password_digest and it would work when authenticating. I'd think it would take the password provided by the user, hash it, and then compare the hash to :password_digest (which couldn't be their password).
This is what I do, which may solve the issue:
before_create :set_temporary_password
def set_temporary_password
self.temporary_password = SecureRandom.hex(5)
end
Send the user self.temporary_password, and when they update it, change temporary_password to nil. Then you can know when a user has a temporary password that requires changing.
I've got a User model that is utilizing mongoid. The model has a password, password_confirmation and encrypted_password field. The password and password_confirmation fields are populated at runtime with the value the user would type on the screen when creating a new user. When I persist, I don't want to persist the unencrypted password values, I only want to persist the value contained in encrypted_password. Is this possible? Is there something I can use to denote certain fields as not being persistable?
Thanks in advance
Chris
Here's a way:
Model only needs the password field and use a before_filter:
def User
before_save :hash_password
attr_accessible :password, :password_confirmation
def hash_password
#todo: improve by adding a salt
self.password = Digest::SHA1.hexdigest(self.password)
end
end
Notes:
Passwords should be stored using a one-way hash, and so passwords should not be 'decryptable'
Use a salt (a random value) and add that to the password before passing it to the hexdigest(). Store the salt in the database as well - say a column called password_salt.
password_confirmation is a virtual attribute and does not need to be defined in the model (rails will manage the details internally)
My User model contains :name, :email, and :password fields. All 3 have validations for length. An "update account" web page allows the user to update his name and email address, but not password. When submitted, params[:user] is
{"name"=>"Joe User", "email"=>"user#example.com"}
Note there is no "password" key because the form doesn't contain such an input field.
When I call
#user.update_attributes(params[:user])
the password validation fails. However, since I'm not attempting to update the password, I don't want the password validation to run on this update. I'm confused why the password validation is running when params[:user] doesn't contain a "password" key.
Note that I want to have a separate web page elsewhere that allows the user to update his password. And for that submission, the password validation should run.
Thank you.
My application does something like this
attr_accessor :updating_password
validates_confirmation_of :password, :if => should_validate_password?
def should_validate_password?
updating_password || new_record?
end
so you have to model.updating_password = true for the verification to take place, and you don't have to do this on creation.
Which I found at a good railscast at http://railscasts.com/episodes/41-conditional-validations
In your user model, you could just ignore the password validation if it's not set.
validates_length_of :password, :minimum => N, :unless => lambda {|u| u.password.nil? }
Using update_attributes will not change the value of the password if there is no key for it in the params hash.
Validation doesn't run against the changed fields only. It validates existing values too.
Your validation must be failing because the password field contains some invalid content that's already saved in the database. I'm guessing it's probably because you're hashing it after validation and you're trying to validate the hashed string.
You can use a virtual attribute (an instance variable or method) that you validate with a custom method, and then assign the hash to the stored password field. Have a look at this technique for ideas.
An app that I am working on uses the following:
validates_confirmation_of :password,
:if => Proc.new { |account|
!account.password.blank?
|| !account.password_confirmation.blank?
|| account.new_record? }
Depending on your requirements, you might want to remove the new_record? check
When password is added then only confirmation will be called and presence will call on create action only
**validates_presence_of :password, :on =>:create**
**validates_confirmation_of :password**