4

I need some help on something that should be very basic. I have followed the excellent tutorial on getting Rails 3 and Authlogic to work together. Its the same very basic authentication shell that is referenced in many places. But I just cant make the log out function work. I have spent days trying all kinds of things. So I need help. Maybe its just something I am not understanding correctly but here is the problem:

The bottom line : @user_session.destroy does not terminate the session.

Details: I am working on a web service so I am only interacting with .xml format requests... and I am using cURL to test.

Everything works fine except for my major issue. I seed the database with Users.

when I do the following without logging in first and cookies.txt is blank (or is some other user's cookie) - >

curl -v -H "Accept: text/xml" -X GET --cookie cookies.txt http://localhost:3000/user.xml 

my request is refused (no session) as expected

When I login using this ->

curl -v -H "Accept: text/xml" -X POST -d 'user_session[email]=eric@xyz.com&user_session[password]=secret' --cookie-jar cookies.txt http://localhost:3000/user_session.xml

a new session is created and I can then do the prior GET to my hearts content. Everything operates correctly in that using another users cookie does not work, using no cookie does not work etc.

BUT... when I log out... doing this ->

curl -v -H "Accept: text/xml" -X DELETE --cookie cookies.txt http://localhost:3000/user_session.xml

the UserSessionsController#destroy action is called

def destroy
  @user_session = UserSession.find
  @user_session.destroy

respond_to do |format|
  format.html { redirect_to(:users, :notice => 'Goodbye!') }
  format.xml  { head :ok }
end
end

and the lines within the action - @user_session = UserSession.find and @user_session.destroy are executed. No errors and testing @user_session = UserSession.find right after the destroy produces nil as expected

HOWEVER... on the next GET request if this same cookie that should now be expired is passed in the request the same database lookup of that particular user's id occurs and the information is delivered - as if a session continues to exist!!

I know this is basic stuff but for completeness here is my ApplicationController:

class ApplicationController < ActionController::Base
#protect_from_forgery
helper_method :current_user_session, :current_user

private

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.record
end

def require_user
 unless current_user
  respond_to do |format|
    format.xml  { head :unauthorized }
  end
  return false
 end
end

def require_no_user
 if current_user
  respond_to do |format|
   format.xml  { head :bad_request }
  end
 return false
end
end

@user_session = UserSession.find in current_user_session - produces the logged out user and will continue to do so... forever if the original cookie created at login in provided.

I cannot retire the session no matter what I try. I even delved into turning off ActiveRecord caching as I saw cache hits occurring. Caching is off and nothing has changed. I figure this is either a gross error of understanding on my part or something with Authlogic I dont understand or does not work.

Any thoughts??

Eric_G
  • 131
  • 2
  • 9

2 Answers2

3

Based on Zabba's excellent answer I came up with solutions for cleaning up the session record on logout and (separately - I wanted both) after a predetermined time after creation. Zabba's answer was fine I just wanted to integrate an answer within Authlogic.

The solutions are very simple and easy. It just was not clear to me how to do it until I found the following two resources. I guess I didn't find these earlier because I didn't know what I was looking for.

For clearing the session on logout - I used this answer and it works well.

Authlogic and multiple sessions for the same user

For timeout I used the second answer here -

Ruby on rails - Authlogic : periodically check if user session is valid

And everything seems to be working great.

Community
  • 1
  • 1
Eric_G
  • 131
  • 2
  • 9
1

In case you haven't found a way around this - the session record is never actually cleaned up. One way to get by this is to use a cron job to clean up sessions on a periodic basis.

Here's a resource I found helpful: Sessions and cookies in Ruby on Rails

There is also a plugin that you can install for more intelligent management of user sessions (including the auto-cleanup feature): Limited Sessions

Zabba
  • 64,285
  • 47
  • 179
  • 207
jli_123
  • 215
  • 1
  • 4
  • Thank you! No I had not found a good explanation or work around. I really appreciate the help. Sorry for the delay in responding but I was far away for the holidays. I am surprised that I hadn't run into this 'feature' of Rails in my searching. – Eric_G Jan 03 '11 at 15:27