0

For my Users Controller, I'd like to always load in the user as the @user instance variable. This is done by loading in the user from an external authorization link with a callback.

Here is a minimal example:

class UsersController < ApplicationController

  before_action :authorize_user
  skip_before_action(:authorize_user, { :only => [:auth_callback] })


  # this is my before action meant to load in the @user instance variable
  def authorize_user

    # if user is not stored in session, get authorization from external link
    if !session.key?(:user_hash)
      redirect_to(external_auth_link)
    
    # otherwise, loads user from hash
    else
      user_hash = session[:user_hash]
      @user = get_user_from_hash(user_hash)
    end
  end

  
  # this is the callback from the external authorization link
  def auth_callback
    user = get_user_from_callback()
    session[:user_hash] = user.to_hash
    # the line in question
    # should I redirect here or what?
  end


  def page1
    # some page using the @user instance variable
    render({:template => "users/page1.html.erb"})
  end


  def page2
    # another page using the @user instance variable
    render({:template => "users/page2.html.erb"})
  end

end

When calling page1 or page2, I'd like the before_action to properly load in the @user instance variable, then return to the appropriate method.

Currently, the before_action works fine when user_hash is already stored in session.

However, when user_hash is not saved in session, it redirects the the external authorization, then goes to the callback, then doesn't know where to go after. It wants me to redirect or render something. How could I get it to redirect to the action (page1 or page2) that was originally called?

Ex: If I call page1 when user_hash is not stored in session it will go to:

  1. authorize_user
  2. The external authorization
  3. auth_callback
  4. page1

I've tried to remove the code unrelated to this issue, but let me know if anything else would be helpful. Thanks for any suggestions.

Christian Doucette
  • 1,104
  • 3
  • 12
  • 21
  • Do you have control over this external authorization? Does it support passing in some extra parameters, that it returns with in the auth callback? – Anuj Jan 07 '21 at 06:57
  • Unfortunately no. Its the Spotify authorization, and it doesn't seem to support that. – Christian Doucette Jan 07 '21 at 15:51

1 Answers1

1

If possible, try getting an additional parameter from the service that handles the auth and redirects to auth_callback. That additional parameter can tell you where to redirect.

If not possible, then you can save the current action to session in authorize_user.

  def authorize_user

    # if user is not stored in session, get authorization from external link
    if !session.key?(:user_hash)
      # save action to session
      session[:redirect_to] = action_name

      redirect_to(external_auth_link)
    
    # otherwise, loads user from hash
    else
      user_hash = session[:user_hash]
      @user = get_user_from_hash(user_hash)
    end
  end

Then use it to redirect in callback. See this topic on getting action name in rails.

Alternatively, you can save the full route or path to the session as well.

Please bear in mind that storing this in session is not the best choice, try getting an additional parameter from auth handler if you can.

F.E.A
  • 307
  • 1
  • 12