Authlogic Perishable_Token Resets on Every Request

AuthLogic perishable_token resets on every request

perishable_token_valid_for isn't doing what you think it is. It's intended to work in tandem with find_using_perishable_token which is intended for things like account validation and resetting a forgotten password. The default timeout is 10 minutes.

The token is supposed to update on every request like it's doing. You can just remove the column if you don't want it. It's completely optional with authlogic.

If you really do want to keep the perishable token but update it completely by hand, you can do disable_perishable_token_maintenance = true

Authlogic Perishable Token Resetting on Failed Login

So we eventually figured out a way around this.

First move was to disable the automatic perishable token handling:

#############
## Authlogic
acts_as_authentic do |c|
.....
c.disable_perishable_token_maintenance = true
.....
end

Then we created our own before_filter on user to mimic the same functionality as the auto handler but ignore changes to the failed_login_count field:

before_save :handle_perishable_token

def handle_perishable_token
unless failed_login_count_changed?
reset_perishable_token
end
end

This basically allows a user to fail at logging in and not reset the perishable token.

Authlogic: How to find if a user was not logged in because the user was not logged in

Rather than check for the actual error, I was able to check for the conditions that cause it using @user_session.attempted_record && !@user_session.invalid_password? &&
!@user_session.attempted_record.active?

Here's my full solution to resending activation emails (after setting up activation using matthook's tutorial):

# /app/controllers/users_sessions_controler.rb
def create
@user_session = UserSession.new(params[:user_session])
if @user_session.save
redirect_back_or_default root_path
elsif @user_session.attempted_record &&
!@user_session.invalid_password? &&
!@user_session.attempted_record.active?
flash[:notice] = render_to_string(:partial => 'user_sessions/not_active.erb', :locals => { :user => @user_session.attempted_record })
redirect_to :action => :new
else
render :action => :new
end
end

# /app/views/user_sessions/_not_active.erb
Sorry, before you can sign in you need to confirm your email address. <%= link_to('Resend confirmation email', resend_activation_users_path(:login => user.login)) %>

# /app/controllers/users_controller.rb
def resend_activation
if params[:login]
@user = User.find_by_login params[:login]
if @user && !@user.active?
@user.deliver_activation_instructions!
flash[:notice] = "Please check your e-mail for your account activation instructions!"
redirect_to root_path
end
end
end

# /config/routes.rb
map.resources :users, :collection => { :resend_activation => :get }

Database write delayed in rails controller?

To answer my question, the problem was not a bad database write - it was that the authlogic library automatically updates the perishable token every time you save the database record. I was sending the token, then saving the user record which reset the token! There is a config setting that I needed:
disable_perishable_token_maintenance = true

That did the trick and fixed my bug

How do I get AuthLogic to skip Password validation?

Doesn't UserSession.create take a user object as it's first argument? If so, couldn't you just do:

UserSession.create(User.find_by_perishable_token(params[:token]))
@current_user_session = UserSession.find

Or is that where you're running into problems?

Authlogic and multiple sessions for the same user

Ok so the perishable token was absolutely not the right path ;)

We "just" need to reset the persistence token every time a user logs in or logs out.
With this in my UserSession model, every user gets logged off from any other session when logging in.

class UserSession < Authlogic::Session::Base
before_destroy :reset_persistence_token
before_create :reset_persistence_token

def reset_persistence_token
record.reset_persistence_token
end
end

Problem with forgot password and authlogic

If I'm reading that trace properly then it looks to me like password_reset_instructions has been declared as a no-argument method. That's what the (1 for 0) complaint is about. Can you check that you have included the user argument in the definition, as below?

class Notifier < ActionMailer::Base  

def password_reset_instructions(user)

end

end

If you've been staring at it for hours it's probably not that simple but worth making sure.

caching with memcached

Are you using the perishable token? This SO question says you can either remove that column, or set disable_perishable_token_maintenance = true to prevent the update-db hit per page load.

As for caching -- in general you can cache non-personalized data for everyone, and personalized data for only that person. So yes, you could cache that block, but the key would need to have the user_id in it.



Related Topics



Leave a reply



Submit