Search code examples
ruby-on-railshttp-redirectdeviseomniauth

How does devise's sign_in_and_redirect method stores location and where does stored location comes from?


I have recently integrated my app as a SP (Service Provider) to a LMS (Learning Management System) that acts as IdP (Identity Provider).

The idea was that once user clicked in my course, published at the LMS tool, he would be immediately redirected to the course's url at my app, using IdP user authentication service (SSO).

It has just partially worked. SSO works but as soon as user is authenticated he is redirected to index page, at my app, not the course's url.

I went to my code to check how login via saml message worked. At omniauth_callback_controller.rb the login method is:

def saml
    student = Student.where(email: request.env["omniauth.auth"]['uid'].to_s).first
    if student
      sign_in_and_redirect student, event: :authentication
    else
        flash[:error] = t 'flash_msg.access_1'
        redirect_to root_path
    end
  end

Then I went to devise to check how "sign_in_and_redirect" method works and it says:

      # Sign in a user and tries to redirect first to the stored location and
      # then to the url specified by after_sign_in_path_for. It accepts the same
      # parameters as the sign_in method.

Code is:

def sign_in_and_redirect(resource_or_scope, *args)
        options  = args.extract_options!
        scope    = Devise::Mapping.find_scope!(resource_or_scope)
        resource = args.last || resource_or_scope
        sign_in(scope, resource, options)
        redirect_to after_sign_in_path_for(resource)
      end

Finally I got to the conclusion that to understand what is going on I would have to understand:

  1. How devise's sign_in_and_redirect method stores location ? According to the method explanation it "..tries to redirect first to the stored location".
  2. Where does stored location comes from ? I suppose it comes from IdP (A GET request ?).
  3. How can I check whether IdP is sendind the location to be stored ? I do not see any GET Request at my logs. Just the POST Request with SAML message.

Can anyone help me with these questions ? Thank you very much.


Solution

  • You can use store_location_for method from devise gem. For example store_location_for(:user, request.full_path) or store_location_for(:user, request.referer), Devise will use that location as after_sign_in_path_for(:user)