3

I have a Rails application that uses static html pages (not in app/views/) sending AJAX requests to the rails server for logging in and out.

I used session for user authentication and when the user logs in, session[:userid] is set and a response 'logged in' is sent back to the static html page. However after logging in when I click the logout button I found the session[:userid] became nil.

Here's my code:

For logging in:

  def login
    # code here
    if encrypt(params[:password]) == @user.password # authenticated
      session[:userid] = @user.id
      render :text => 'logged in'
    else # wrong password
      render :text => 'password not correct'
    end
  end

For logging out

  def logout
    # here session is no longer available  
    session[:userid] = nil  
    render :text => 'logged out'
  end

Log in page:

    <button id='login_button'>Log in</button>
    <script type="text/javascript" charset="utf-8">
        $('#login_button').click(function() {
            $.ajax({
                type: 'POST',
                url: 'http://localhost:3000/user/login',
                data: { username : $('#login_username').val() , password : $('#login_password').val() }
            }).done(function(data) {
                if (data == 'logged in') {
                    window.location = 'logged_in.html';
                } else {
                    alert(data);
                }
            });
        });
    </script>

And for logging out:

<button id='logout_button'>Log out</button>
<script type="text/javascript" charset="utf-8">
    $('#logout_button').click(function() {
        $.ajax({
            type: 'POST',
            url: 'http://localhost:3000/user/logout',
        }).done(function(data) {
            console.log(data);
        });
    });
</script>

Log for login:

Started POST "/user/login" for 127.0.0.1 at 2012-10-12 16:28:46 -0500
Processing by UserController#login as */*
  Parameters: {"username"=>"name", "password"=>"[FILTERED]"}
  User Load (0.1ms)  SELECT "users".* FROM "users" WHERE (username = 'name')
Completed 200 OK in 12ms (Views: 0.3ms | ActiveRecord: 0.6ms)

Log for logout:

Started POST "/user/logout" for 127.0.0.1 at 2012-10-12 16:28:50 -0500
Processing by UserController#logout as */*
{} <--------------------------------------- here I printed out session
  Rendered text template (0.0ms)
Completed 200 OK in 1ms (Views: 0.7ms | ActiveRecord: 0.0ms)

Is it the problem of AJAX, that we cannot use session for AJAX requests from the client?

Thanks in advance.

Guanlun
  • 1,598
  • 2
  • 18
  • 29

1 Answers1

6

Do you have "protect_from_forgery" set? If so, this is causing the problem. When Rails receives the Ajax call and doesn't find the correct CSRF token, it will close the session.

Instead of turning the protection off globally, it would be better to turn it off just for any of the calls from the static page by putting something like this in the relevant controller:

skip_before_filter :verify_authenticity_token, :only => [:login, :logout]
Max Dunn
  • 1,244
  • 9
  • 13
  • 1
    thanks but it does seem to work even if I removed `protect_from_forgery` – Guanlun Oct 12 '12 at 20:04
  • You might want to double check the log file to make sure forgery protection is off by searching for the line: "WARNING: Can't verify CSRF token authenticity" – Max Dunn Oct 12 '12 at 20:37
  • I remove the WARNING message by using `protect_from_forgery :only => :create`, but when I tried to log `session` in `logout`, it still prints only `{}`, any ideas? – Guanlun Oct 12 '12 at 21:02
  • Can you please add your log to the question so we can take a closer look. – Max Dunn Oct 12 '12 at 21:39
  • Hmm, short log, no clues there. Could there be an issue with storing sessions in general? What type of session storage are you using? Here is a good post on [storing sessions in the database](http://stackoverflow.com/questions/2588241/rails-sessions-current-practices-especially-for-rails-3). Might be an interesting test to create two methods like "set" and "show" where you save something else in the session and see if it is saved. – Max Dunn Oct 12 '12 at 22:20
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/17958/discussion-between-max-dunn-and-guanlun) – Max Dunn Oct 12 '12 at 22:32