Prevent AuthLogic from automatically logging in after creating new user
Last week, I was helping my friend solve an annoying issue in AuthLogic which took me and my colleagues few hours to figure out the solution. And I would like to share it here so that you can avoid this issue in the future and save your day.
We were working on a feature which allows guest user to add items to his shopping cart and signing in later. We had done this kind of feature several times before but mostly with Devise, so we had no much experience working with AuthLogic. But the basic idea is still the same: we create a fake user in database and store that fake user in the session and treat it as current_user. For example, in my application_controller
def current_or_guest_user
if current_user
guest_user.destroy
session[:guest_user_id] = nil
current_user
else
guest_user
end
end
def guest_user
User.find_by_id(session[:guest_user_id]) || create_guest_user
end
def create_guest_user
user = User.create_guest_user
session[:guest_user_id] = user.id
user
end
def current_user_session
return @current_user_session if defined?(@current_user_session)
@current_user_session = UserSession.find
end
def current_user
return @current_user if defined?(@current_user)
@current_user = current_user_session && current_user_session.user
end
From now on, instead of using current_user
method like we usually do, we will use current_or_guest_user
for reference.
This method would work very fine in Devise but for some reasons, it did not work with AuthLogic. We realized that the guest user was automatically logged in by AuthLogic. And that was the reason why it did not return correct guest user from the database and tried recreating new guest user on every 2 requests. Why every two requests? Here are the requests:
-
First request: guest user is created, and it become the
current_user
because of strange behavior of AuthLogic -
Second request: we detect and it seems like you are logged in, so we will try destroying the
guest_user
which is exactly the current user. And you will be logged out from the system because user object has just been destroyed. -
Third request: You have already logged out, the same thing happen like the first request.
Solution
How would we solve this? After hours of searching and asking the community, here we come the solution. As far as we understand, AuthLogic would automatically log in the user who has just been created. It means that when you do this:
user = User.new
#set attributes here
#user.abc = '123'
user.save #it become wrong here
This new user
will be signed in as default.
If you don't want this to happen, you need to use different method which is the key of this post
user.save_without_session_maintenance
And tada, your application now works as you expected, your guest user will not be auto-logged in and destroyed.
Hopefully this post is helpful to you and please share it with your friend so that they can avoid similar issue we had before.