sso - Devise/OmniAuth Override default callback url
rails facebook login (2)
I'm using Devise 3.5 with Omniauth in a Rails 4 app. I've created an integration with Facebook that allows a user to connect their Facebook account to my app. Currently when the user clicks the connect button, they're sent to
/user/auth/facebook and then redirected to the callback url that Omniauth generates:
/user/auth/facebook/callback. What I'd like to do is manually override this callback url in some cases - meaning that I don't want to override it in an initializer - with a fully qualified url. For example, if a user starts out on
http://www.example.com/ I might want to override the default callback url with
My app has dynamic subdomains and a user will (almost) always begin the authentication process on a subdomain. Unfortunately it seems that Facebook doesn't support wildcards in oauth redirect urls, which is why I want the ability to detect if a user is on a subdomain and adjust the callback url to something that I have whitelisted on my Facebook app so that the authorization process succeeds.
From what I've read, the url helper
omniauth_authorize_path accepts additional arguments to be passed on as parameters. I've tried passing a custom callback path in like so, but without success:
user_omniauth_authorize_path(:facebook, callback_path: @custom_callback)
I've also tried changing
redirect_uri, but nothing seems to work. When I look at the link that's generated, it does indeed include the callback as a parameter in the url, but when I click the link, I'm redirected back to the default callback url instead of the custom callback url.
Here's how I solved this problem. I'm sure there are other ways, but this seems like the simplest most elegant solution I could come up with.
config/routes.rb I set up an
auth subdomain. All my Oauth connect requests will start on different subdomains and then Facebook is set up to forward those users back to the
constraints AuthRedirect do devise_scope :contact do get '/auth/facebook/callback' => 'omniauth_callbacks#facebook' post '/auth/facebook/callback' => 'omniauth_callbacks#facebook' end end
/lib/auth_redirect.rb. This just checks if the subdomain is
auth and captures that traffic. This is placed at the top of my routes list so as to take precedence over other subdomains.
class AuthRedirect def self.matches?(request) request.subdomain.present? && request.subdomain == 'auth' end end
Then in my client, when a user clicks the
Connect with Facebook button, I send them to
/auth/facebook?contact_id=<id>. From here Devise directs them to Facebook, which then redirects them back to
OmniauthCallbacksController#facebook I can pull the user's id from the omniauth params like so:
auth = env["omniauth.auth"] contact = Contact.find(env['omniauth.params']['contact_id'])
From here I can persist the credentials to the database and the redirect the user back to the appropriate subdomain. This solution avoids problems with CSRF tokens and more importantly does not require me to use Ruby/ERB to build the omniauth authorize path that the user is sent to when they click the connect button.
have you tried with redirect_uri ?
user_omniauth_authorize_path(:facebook, redirect_uri: @custom_callback)
EDIT: sorry I missed the second part of your post.
I actually have the same problem in production but it works perfectly on a staging environment. The only difference is about the callback url on staging which has one more subdomain *.staging.domain.com
By the way you can provide a static callback_url in the devise initializer file:
config.oaumniauth :facebook, ..., callback_url: 'url right here'
I'm on this issue this yesterday. Either I provide a static callback url but facebook raises me an CRSF error:
omniauth: (facebook) Authentication failure! csrf_detected: OmniAuth::Strategies::OAuth2::CallbackError, csrf_detected | CSRF detected
Or I let devise set the callback_url dynamically which gonna look like
and in this case I get a straight non matching/whitelisted callback url during FG loggin in process.
GOOD! I made it. I'm able to get oauth login in with wildcard subdomain.
- Provide a static callback_url in your devise initializer
- add the domain to your session store as : domain: ".domain.com"
With that I'm getting neither CRSF error nor nunmatching CB url/whitelisted.
Hope it'll work for you !