views:

337

answers:

1

I've been banging my head against this one for a couple days now:

I've got a RoR app using AuthenticatedSystem to require authentication for some of the resources. A before_filter checks to see if the user has logged in. If not, it grabs the request.request_uri and puts it in a session variable (session[:return_to]), then sends the user to the login page via a 302 redirect message. Then after login, the user is redirected back to the url in session[:return_to].

This works great in IE and Firefox. In Safari, the request.request_uri on the initial before_filter is blank, and the session controller always redirects to the main page.

Has anybody encountered this before? The only clue I have is that the Web Inspector for Safari doesn't even show the request for the initial page, only the request for the login. In Firefox, I'm seeing both requests.

Here's the before_filter:

def login_required
  if !authorized?
    session[:return_to] = request.request_uri
    redirect_to new_session_path
  end
end

Here's the session/create:

def create
  self.current_user = User.authenticate(params[:login], params[:password])
  if logged_in?
    if params[:remember_me] == "1"
      current_user.remember_me unless current_user.remember_token?
      cookies[:auth_token] = { :value => self.current_user.remember_token , :expires => self.current_user.remember_token_expires_at }
    end
    redirect_back_or_default('/')
    flash[:notice] = "Logged in successfully"
  else
    flash.now[:error] = "Authentication failed."
    render :action => 'new'
  end
end

Any ideas?

A: 

So, just in case someone runs across this...

The answer seems to be in Safari's aggressive blocking of 3rd party cookies. This error was occurring in a bookmarklet, which is basically an iframe added into a third-party website's DOM when the user decides to use it (don't worry, it's for something similar to FriendFeed's bookmarklet - basically a way for users to add content from other sites without leaving those sites).

Anyway, in this circumstance, Safari treats the session cookie that Rails tries to set as being a third-party, even though it's being set from inside an iframe. So, upon redirect, all session variables are being lost.

Two possible solutions present themselves

  • tell users to allow third-party cookies (not happy with this option)
  • pass the "return_to" url along with the form data and retrieve this in the session controller (better option)
jrb