changing password by signed in user works, but subsequent logins are immediately invalidated

965 views
Skip to first unread message

Mike Atlas

unread,
Jan 29, 2014, 4:06:13 PM1/29/14
to plataforma...@googlegroups.com
I have a customized user's settings page which allows a user to enter a new password. After changing the password, the user can continue to use the app without issue. However, if they log out, they are only able to log in for a moment before immediately having their session invalidated again. The strangest solution to fix the user that can't "stay" logged in (for more than a moment) is for me to go into the rails console, change the user's email address to something else, save it, change it back to the original email address, save it again. After that, the user can log in and remain logged in. What could be going on here? I also cannot replicate this locally, only in production.

My password update controller action is the following:

def update_my_password
    @user = User.find(current_user.id)
    authorize! :update, @user

    if @user.valid_password?(params[:old_password])
      @user.password = params[:new_password]
      @user.password_confirmation = params[:new_password_conf]
      if @user.save
        sign_in @user, :bypass => true
        head :no_content
        return
      end
    else
      render :json => { "error_code" => "Incorrect password" }, :status => 401     
      return
    end

    render :json => { :errors => @user.errors }, :status => 422
  end

My session_store.rb is set:
MyApp::Application.config.session_store(ActionDispatch::Session::CacheStore,
:expire_after => 3.days)

Any help or tips or ideas as to what could be going on would be a big help. 

and...@benjamin.dk

unread,
Jan 30, 2014, 10:07:41 AM1/30/14
to plataforma...@googlegroups.com
Hey,

Maybe you can start by giving: rails, ruby and devise version.

Second: What is the differences between your production and development environments? Caching, server, etc...

Third: Why do you have an action called  update_my_password on an PasswordUpdateController? or at least thats what I understood.Why not override the update action of this: http://rubydoc.info/github/plataformatec/devise/master/Devise/PasswordsController

Fourth: Was this working before? what was the change that broke it? I can see you are rendering json is to be used as an API? to another APP?

all the best,

Andre

Mike Atlas

unread,
Jan 30, 2014, 3:34:29 PM1/30/14
to plataforma...@googlegroups.com
Hi Andre,

Rails 4.0.1, ruby 2.0, devise 3.2.2. I am using memcached locally and memcachier on production (heroku) for the session store.

I am going by solution 3 in this guide:

I'm rendering json responses because the update password action is performed with an ajax POST request from my application - it is not an open API; the action is restricted with CanCan to updating the password of the current user via the first two lines in the action:

  @user = User.find(current_user.id)
  authorize! :update, @user

Anyways, here's something interesting: Despite the fact that the user is unable to remain signed in after a password change (note: not a password reset!), I'm able to "switch" to their account and remain logged in, when using the "switch_user" gem: https://github.com/flyerhzm/switch_user - this is a gem that enables you to rapidly switch accounts by bypassing the need for logging in, and, somehow, bypassing whatever is causing my problem in production (note: I'm testing switch_user in a staging server, not actual production). The meat of the switch_user login action is here:


Does this help provide anymore insight? I've tried using :cookie_store for the session with no luck; it doesn't appear to be cookie related (particularly when switch_user works fine).

Thanks,
Mike

Mike Atlas

unread,
Feb 3, 2014, 3:09:01 PM2/3/14
to plataforma...@googlegroups.com
For all who are still following, I have yet to track this down. However, I am onto a new clue:

1) User changes their password
2) User attempts to log in: They are successful for a moment, but immediately logged out again (usually by the first XHR request, which returns 401 unauthenticated)
3) If I restart the server (heroku restart), User can log in with the new password and remain logged in as expected

What would restarting the server do exactly regarding sessions that would "fix" this problem? I think, one thing, perhaps, this may have to do with the fact that I'm running Rails on the puma web server, multi-threaded. Subsequent requests *sometimes* work, and *sometimes* don't.

As a test, I changed my puma thread (on my staging server) to run 1 worker and 1 thread only. Sure enough, actually, it seems that my problem goes away!!!

So... now what do I do to fix this in production? I can't make it a single-thread, that would defeat the purpose of doing threadsafe rails 4 with puma....

Mike Atlas

unread,
Feb 3, 2014, 6:47:55 PM2/3/14
to plataforma...@googlegroups.com
I posted this now on StackOverflow as I've narrowed it down to some sort of issue with Puma and multithreading:

and...@benjamin.dk

unread,
Feb 5, 2014, 6:03:04 AM2/5/14
to plataforma...@googlegroups.com
I mean this is a hard one since Devise is supposed to be thread safe!

Have you tried to use devise without your custom controllers to see if it works with your puma setup? Then if does not work we will know the problem is on devise. If it does then we can guess its either from your custom controller or from the puma configuration.

After with your custom controller you can try to configure other multithread server like the ones here:


And if it works we know is from the puma configuration if it doesn't its from the code!

then we can rule out some options!
Reply all
Reply to author
Forward
0 new messages