Return to the previous or a specific page after login with OmniAuth

kinopyo avatar

kinopyo

It's a common practice to return the user to the previous page or a specific page after he/she successfully logged in. If you're using OmniAuth, it's already well supported in the gem! The 🔑 is request.env['omniauth.origin'].

Scenario: return to the previous page

Using the same code example from omniauth gem:

sessions_controller.rb

class SessionsController < ApplicationController def create user = User.find_or_create_from_auth_hash(auth_hash) Current.user = user redirect_to '/' # we want to redirect to previous page here end private def auth_hash request.env['omniauth.auth'] end end

The previous page, or to be specific, the request referrer is stored in request.env['omniauth.origin'], so you could write like this:

def create
  # ...
  redirect_to origin
end

private

def origin
  request.env['omniauth.origin']
end

Since by default it's the same as the request referrer, the code isn't that much different than the Rails redirect_back. So if your app is simple enough, the code below would also work:

redirect_back fallback_location: root_path

Then what's the advantage of using request.env['omniauth.origin']? Let's see the next scenario.

Scenario: return to a specific page

When would you want to redirect the user to a specific page rather than previous one?

I can think of some scenarios like the typical "Find followings on Twitter" flow in which you'd usually see a list of people you're following after connecting with Twitter, or "Connect to Github" flow in which you'd choose to import some repos.

link_to 'Find followings on Twitter', "/auth/twitter?origin=#{twitter_followings_path}"
link_to 'Connect to Github', "/auth/github?origin=#{github_repos_path}" 

And you can reuse the same controller code above to handle it:

redirect_to request.env['omniauth.origin']

Customize the origin param

You can also customize the origin param name in the link if you want.

config/initializers/omniauth.rb

provider :twitter, ENV['KEY'], ENV['SECRET'], origin_param: 'return_to'

Then, your link would be "/auth/twitter?return_to=...", but in the controller, you'd still need to use the same key to access that link: request.env['omniauth.origin'].

Note that you can access any params you pass in the auth link via request.env['omniauth.params']. The origin is just a more convenient and more specific way to handle where to return the user to.

Recap

  • Given /auth/twitter
    • request.env['omniauth.origin'] = request referrer
  • Given /auth/twitter?origin=URL
    • request.env['omniauth.origin'] = URL
  • Given /auth/twitter?origin=URL&foo=bar
    • request.env['omniauth.params'] = { "origin" => URL, "foo" => "bar" }
  • Customize origin_param: 'return_to'
    • so to use /auth/twitter?return_to=URL
kinopyo avatar
Written By

kinopyo

Indoor enthusiast, web developer, and former hardcore RTS gamer. #parenting
Published in Rails
Enjoyed the post?

Clap to support the author, help others find it, and make your opinion count.