Return to the previous or a specific page after login with OmniAuth
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']
origin
param
Customize the 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
- so to use
Clap to support the author, help others find it, and make your opinion count.