Peter Nixey
Peter Nixey

Reputation: 16565

Does the User model need :password and :password_confirmation to be set as attr_accesible in authlogic?

I've been trying to setup Authlogic for the first time but I'm confused.

I have set it up as per the example in the authlogic_example code however it doesn't appear to run:

u = User.new(:password=>'testpass',
             :password_confirmation => 'testpass', 
             :email => '[email protected]')
=> #<User id: nil, email: "[email protected]", created_at: nil, updated_at: nil, 
          first_name: nil, last_name: nil, crypted_password: nil, 
          password_salt: nil, persistence_token: nil>
 >> u.valid?
 => false
 >> u.errors
 => #< OrderedHash {:password=>["is too short (minimum is 4 characters)"], 
                    :password_confirmation=>["is too short 
                                            (minimum is 4 characters)"]}>

It looked like :password and :password_confirmation simply weren't being set so in class User I made :password and :password_confirmation accessible attributes:

class User < ActiveRecord::Base
  acts_as_authentic
  attr_accessible :password, :password_confirmation # changed code
end

That worked:

>> u = User.new(:password=>'testpass',:password_confirmation => 'testpass', 
                :email => '[email protected]')
=> #<User id: nil, email: "[email protected]", created_at: nil, updated_at: nil, 
          first_name: nil, last_name: nil, 
          crypted_password: "446edcbee34254ea83b8d469baef2dc34d723e710faf22efb97...", 
          password_salt: "hZFVKUo66meyrZ97Gb", 
          persistence_token: "b469fefd82a91683bf51b5eb9dbc15563b569a93ce973a42595...">
>> u.valid?
=> true

Whilst this worked, I'm concerned that I've been doing something wrong because in the authlogic_example, there are no attr_accessible set in user:

# Authlogic_example code
class User < ActiveRecord::Base
  acts_as_authentic
end

Why is it that the authlogic_example code works without explicitly setting the attributes to be being accessible but mine doesn't?

Upvotes: 3

Views: 1161

Answers (3)

rogermushroom
rogermushroom

Reputation: 5586

To add to Peter Nixey's answer, to resolve this problem in rails 3 I changed the following:

# application.rb
config.active_record.whitelist_attributes = false #it was true

When set to true, a whitelist is enforced for all attributes that can be mass assigned. This needs to be disabled or you can add them to the white list with

attr_accessible <your attributes> 

Edit

As Peter quite rightly points out in the comments; by setting the configuration to false you leave yourself open to mass_assignment attacks, so using the white list is the securest option,

Upvotes: 0

Peter Nixey
Peter Nixey

Reputation: 16565

I suddenly realised what caused my problem.

I had previously changed the default setting for mass_assignment in a config file to enforce that all attributes were protected unless declared otherwise.

An obvious mistake in retrospect but hopefully this might save someone else some time too

Upvotes: 3

Spyros
Spyros

Reputation: 48636

Attr_accessible is a safety feature. It tells your model to only save the mentioned values, upon a mass assignment (like save). Im' pretty sure that you will notice a Warning on mass assignment if you look at your logs.

If you have try to save a model even with a single accessible attribute, ONLY this will be saved in a mass assignment. Thus, if you have :password accessible but :password_confirmation not accessible, only :password will be inserted, and you will get a warning.

I think that this is probably the reason why you get this behaviour.

Upvotes: 1

Related Questions