How to Handle Omniauth Callbacks in Multiple Environments

How to handle OmniAuth callbacks in multiple environments?

Create another one facebook app with domain localhost:3000 for development and create
config.yml in the config directory

development:
facebook_api_key: 656756786867868
facebook_api_secret: 4sdffdh6u345436

production:
facebook_api_key: 45778799
facebook_api_secret: fghjkbbcbcbcbcb

Now add load_config.rb to the initializers folder

# load config
AppConfig = YAML.load_file(Rails.root.join('config', 'config.yml'))

# Override config options by correct environment
env_options = AppConfig.delete(Rails.env)

AppConfig.merge!(env_options) unless env_options.nil?

And finally add this to the omniauth.rb

Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, AppConfig['facebook_api_key'], AppConfig['facebook_api_secret']
end

It will take your keys depending on rails environment. That's all, hope it helps you.

Is there a way to manage multiple redirect URI for different environments in the Instagram Developer website?

Best choice in my opinion would be to create two clients (apps) on Instagram:

  • one for production
  • one for dev

You will then have two sets of credentials.

For example with Rails switch from one config to the other depending on the current environment:

if Rails.env == "development" || Rails.env == "test"
# load development instagram client config
else
# load production instagram client config
end

How to setup local development environment for Rails when using Devise Omniauth with GitHub?

I've handled this in the past by creating two apps with the OAuth service. One is a production app that redirects back to my production domain and the other is an app that redirects back to my development environment. You can add a third app for a staging environment, later when you start using one.

Then I use environment variables from the app_key and app_secret_key within my own app, so in a development environment I'm authenticating against the development GitHub app and in production I'm authenticating against the production GitHub app.

With specified endpoints, this is the only solution I've found that worked. If you can provide redirect endpoints with the authentication request, then you can get away with a single app, but this is generally insecure and not a common feature at this point.

Devise/OmniAuth Override default 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.

In 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 auth.example.com subdomain.

constraints AuthRedirect do
devise_scope :contact do
get '/auth/facebook/callback' => 'omniauth_callbacks#facebook'
post '/auth/facebook/callback' => 'omniauth_callbacks#facebook'
end
end

Here is /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 https://auth.example.com/.

Then in 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.

How to use and configure omniauth with yahoo, google, facebook strategies in various environments?

As for your first question:

You need to create apps for Facebook, Google and Twitter to allow the use of their OAuth protocol. As for Yahoo, I don't know. Is Yahoo still relevant? Just kidding. For a list of all the available Omniauth provider strategies, go here.

So, Facebook:

https://developers.facebook.com/apps
Create app. You'll be given an API Key and an API Secret.
Settings > Basic > Website > Site URL:
your_website_callback_url for production

Twitter:

https://apps.twitter.com/
Create app. You'll be given an API Key and an API Secret.
Settings > Callback URL:
your_website_callback_url for production

Google:

https://console.developers.google.com
Create app. You'll be given an API Key and an API Secret.
Services > Select necessary services and scopes
APIs & auth > Credentials > Create New Client ID:
http://localhost:3000/ for development/testing
your_website_callback_url for production

Then, your Gemfile:

gem 'omniauth-facebook'
gem 'omniauth-twitter'
gem 'omniauth-google-oauth2'

Create a file to setup your strategies. The convention is naming it omniauth.rb. There are a bunch of different options available to each provider, you'll have to investigate what those are:

# config/initializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, 'FACEBOOK_KEY', 'FACEBOOK_SECRET', {
secure_image_url: 'true',
image_size: 'square'
}

provider :twitter, 'TWITTER_KEY', 'TWITTER_SECRET', {
secure_image_url: 'true',
image_size: 'normal'
}

provider :google_oauth2, 'GOOGLE_KEY', 'GOOGLE_SECRET', {
image_size: 50,
image_aspect_ratio: 'square'
}
end

And then follow this railscast and this wiki. You should be using environment variables like ENV['FACEBOOK_KEY'] and setting them in the console so that you can change them during runtime and so that they don't get pushed in a certain file into your repositoriy (specially if you have a public one). Here's a solution to this problem.

Finally, you should search for each provider's gem wiki for extra info. For instance, facebook's omniauth gem readme provides an example of an authentication hash returned by Facebook when a user authenticates through Facebook. You can then use this information to customize your user model (update his full name or his image, according to what you want to do). It also mentions how you can ask for extra permissions to access user data that is not publicly available.

Edit: To answer your question:

Like I said, I really like Railscasts and I followed 2 episodes where Devise and OmniAuth were integrated. In those episodes, the omniauth-openid gem is used to authenticate with Google. The downside of it is that since you don't register an app, you can't customize the authentication prompt. With Facebook and Twitter you're able to choose a name, type a description and upload the logo of your application. You can also set links to the "Privacy" and "Terms of Use" pages on your website. All these little details will appear to the user when he tries logging in with those services and, as you can imagine, they affect your user conversion rates.

With omniauth-openid you can't customize the prompt and the information you get is limited (only the email and the name associated with the account). If that's all you need, then you're all set. If, however, you want to get the user's image, maybe access other private info only available from the user's Google+ profile, then it's probably better to just go with omniauth-google2.

The good thing about OmniAuth is that once you get the basic foundation working, adding other providers is as easy as registering an app, getting an API key and secret and including a certain gem. I'd suggest starting first with Facebook since it's the most popular service and as such is the one with the most documentation (or at least the one with more questions here on SO). From there, build on your application and add other authentication methods.

OmniAuth: Guarding against multiple accounts for the same user

Your gut feeling is correct. You'll have to provide a merge tool for your user... or you can ignore the problem.

OmniAuth using wrong callback port in a reverse proxy setup

I had a look into the OmniAuth source and found out that the callback mechanism internally uses a method named full_host that looks up the configuration variable and then builds the first part of the URI - have a look at oa-core-0.2.6/lib/omniauth/strategy.rb

The configuration variable can be a String (as in your case), or a Proc, or nil (or anything else). In the latter case, the request URI is parsed, chopped, and returned.

I think that we can't solve our common problem by just setting an environment variable in Apache (this probably should be done at a lower level, inside the ruby application stack), but after some experimentation I've found this works well enough for me:

OmniAuth.config.full_host = lambda do |env|
scheme = env['rack.url_scheme']
local_host = env['HTTP_HOST']
forwarded_host = env['HTTP_X_FORWARDED_HOST']
forwarded_host.blank? ? "#{scheme}://#{local_host}" : "#{scheme}://#{forwarded_host}"
end


Related Topics



Leave a reply



Submit