omniauth OAuthException & OAuth::Unauthorized - ruby-on-rails

I have installed omniauth 1.0. Also I have oauth-0.4.5, oauth2-0.5.1, omniauth-facebook-1.0.0, omniauth-twitter-0.0.6.
omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
provider :developer unless Rails.env.production?
provider :facebook, ENV['167257285348131'], ENV['c8c722f697scb2afcf1600286c6212a9'], :scope => 'email,offline_access,read_stream', :display => 'popup'
provider :twitter, ENV['fma2L22ObJCW52QrL7uew'], ENV['4aZfhCAOdiS7ap8pHJ7I1OZslFwVWWLiAMVpYUI']
end
session_controller.rb
class SessionsController < ApplicationController
require 'omniauth-facebook'
require 'omniauth-twitter'
require 'omniauth'
def create
#user = User.find_or_create_from_auth_hash(auth_hash)
self.current_user = #user
redirect_to '/'
end
def auth_hash
request.env['omniauth.auth']
end
end
Also I add
'omniauth'
'omniauth-facebook'
'omniauth-twitter' gems to gemfile
There are two problems:
When I go http://localhost:3000/auth/facebook I get
{
"error": {
"message": "Missing client_id parameter.",
"type": "OAuthException"
}
}
And the link graph.facebook.com/oauth/authorize?response_type=code&client_id=&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Ffacebook%2Fcallback&parse=query&scope=email%2Coffline_access%2Cread_stream&display=popup
And there is no client_id!!!
When I go to http://localhost:3000/auth/twitter I get OAuth::Unauthorized
401 Unauthorized
Any ideas?

Alex D. is correct in that the ENV[] breaks it. To create omniauth.rb so that it uses different keys in different environments just put:
provider :twitter, TWITTER_KEY, TWITTER_SECRET
in omniauth.rb
and then in your environment config files (config/environments/development.rb, etc.) put the key you want to use for that environment.
config/environments/development.rb:
TWITTER_KEY = 'aaaaaaa'
TWITTER_SECRET = 'aaaabbbbbb'
config/environments/production.rb:
TWITTER_KEY = 'ccccccc'
TWITTER_SECRET = 'ccccdddddd'

ENV['something']
looks into your environment vars for "something", so it would expect
something='12345'
so you should do it like that
export AUTH_FB_KEY='....'
export AUTH_FB_SECRET='...'
check with
env
and update your config
provider :facebook, ENV['AUTH_FB_KEY'], ENV['AUTH_FB_SECRET']
if you use heroku
heroku config:add AUTH_FB_KEY='....'

There have been breaking changes made in omniauth 1.0 - https://github.com/intridea/omniauth
OmniAuth 1.0 has several breaking changes from version 0.x. You can
set the dependency to ~> 0.3.2 if you do not wish to make the more
difficult upgrade. See the wiki for more information.
I would try reverting omniauth to 0.3.2:
gem install omniauth --version '~> 0.3.2'
or if you're using bundler, in your Gemfile:
gem omniauth, '~> 0.3.2'

Related

retrieve first_name and last_name from auth hash using omniauth-google-oauth2 gem

I have a rails 4.2.7 app setup using the omniauth-google-oauth2 gem, and I would like to retrieve the first_name and last_name from the auth hash.
I was able to do this with the omniauth-facebook gem by modifying the devise.rb to look like the following,
devise.rb
# Omniauth / Oauth2 settings
callback_url = if Rails.env == "development"
ENV['FB_CALLBACK']
else
ENV['FB_CALLBACK_PROD']
end
config.omniauth :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'], callback_url: callback_url,
:scope => 'email',
:info_fields => 'email, first_name, last_name'
# Google - OmniAuth
require 'omniauth-google-oauth2'
config.omniauth :google_oauth2, ENV["GOOGLE_CLIENT_ID"], ENV["GOOGLE_CLIENT_SECRET"]
However, I can't seem to figure out how to retrieve the first_name / last_name using omniauth-google-oauth2. Any help would greatly be appreciated.
#chris from omniauth-google-oauth2, in your callback controller action,
auth = request.env['omniauth.auth']
request.env['omniauth.auth'] will contain a hash of users' auth session, with which basic user info are persisted in info i.e. auth["info"]
auth
====
{
.....
"info"=>
{"name"=>"Username",
"email"=>"Useremail",
"first_name"=>"firstname",
"last_name"=>"lastname",
"image"=> "image_url",
"urls"=>{"Google"=>"https://plus.google.com/xxxxxxxxxxxxxxxxx"}
}
....
}

Google OAuth 2.0 and Devise - "error" : "redirect_uri_mismatch"

I configured Devise to use omniauth with Facebook and Google. It works fine with Facebook but I face a problem with Google.
I get this error again and again:
ERROR -- omniauth: (google_oauth2) Authentication failure! invalid_credentials: OAuth2::Error, redirect_uri_mismatch:
{"error" : "redirect_uri_mismatch"}
[localhost] [127.0.0.1] [6a9377fe-d0b3-42]
RuntimeError - Could not find a valid mapping for path "/users/auth/google_oauth2/callback":
devise (3.5.2) lib/devise/mapping.rb:49:in `find_by_path!'
I tried several URIs in the Google console but anyone didn't seem to work:
Gemfile
# Social Networks Authentification
gem 'omniauth'
gem 'omniauth-facebook'
gem 'omniauth-google-oauth2'
devise.rb
config.omniauth :facebook, ENV['OAUTH_FACEBOOK_ID'], ENV['OAUTH_FACEBOOK_SECRET'],
scope: 'public_profile', image_size: {height: 1600}, info_fields: 'name, id, first_name, last_name, gender, hometown, cover, email, link' # list of permissions
# Not working, "error" : "redirect_uri_mismatch"
config.omniauth :google_oauth2, ENV['OAUTH_GOOGLE_ID'], ENV['OAUTH_GOOGLE_SECRET']
omniauth_callbacks_controller.rb
def self.provides_callback_for(provider)
class_eval %Q{
def #{provider}
#user = User.find_for_oauth(env["omniauth.auth"], current_user)
if #user.persisted?
handle_redirect("devise.#{provider}_uid", "#{provider}".capitalize)
else
session["devise.#{provider}_data"] = env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
}
end
[:facebook, :google_oauth2].each do |provider|
provides_callback_for provider
end
def handle_redirect(_session_variable, kind)
# here we force the locale to the session locale so it siwtches to the correct locale
I18n.locale = session[:omniauth_login_locale] || I18n.default_locale
sign_in_and_redirect #user, event: :authentication
set_flash_message(:notice, :success, kind: kind) if is_navigational_format?
end
omniauth_controller.rb
class OmniauthController < ApplicationController
def localized
# Just save the current locale in the session and redirect to the unscoped path as before
session[:omniauth_login_locale] = I18n.locale
redirect_to user_omniauth_authorize_path(params[:provider])
end
end
routes.rb
devise_for :users, skip: [:session, :password, :registration, :confirmation], controllers: { omniauth_callbacks: 'omniauth_callbacks' }
localized do
get 'auth/:provider' => 'omniauth#localized', as: :localized_omniauth
devise_for :users, :path => 'accounts', skip: :omniauth_callbacks, :controllers => {sessions: 'sessions', registrations: 'registrations', passwords: 'passwords'}
end
user.rb
devise :omniauthable, :omniauth_providers => [:facebook, :google_oauth2]
I have the issue both in local and production.
Can anyone help me please? I really don't know what else I can do.
Allright, finally found out what was the problem...
The 'omniauth-google-oauth2'gem only works with version 1.3.1 of the 'omniauth-oauth2' gem.
So I changed my Gemfile like this:
# Social Networks Authentification
gem 'omniauth-oauth2', '~> 1.3.1' # Don't touch that unless you don't want Google omniauth to work!
gem 'omniauth-twitter'
gem 'omniauth-facebook'
gem 'omniauth-linkedin'
gem 'omniauth-google-oauth2' # Works only with omniauth-oauth2 v 1.3.1
And now everything works fine!
See this thread for more details.
Please check following steps to resolve issue
Step1. Error: redirect_uri_mismatch as the following error, copy the following link text The redirect URI in the request, http://yourlinks:3000/, does not match the ones authorized for the OAuth client. Visit...
Step2. Login into Google Console Api, go to Credential, Choose your Api and past the above link to Authorized redirect URIs section
Step3. Save and test again
Thank you.
I had the same issue and i made a plenty of mistakes, which i corrected by following these steps:
First check whether the redirect url in the google Credentials is correct,
Then check the version of "omniauth-google-oauth2", changing version of this gem worked for me.
Gemfile contains
gem "gmail"
gem "omniauth-google-oauth2"

How can I send tweets to my Twitter account?

Every time the user post a comments, I want it to send the same comment to my Twitter automatically.
First of all, I have it already done with Twitter developer settings.
So I made a test action in my App to make it send a tweet to my Twitter account.
However, it says this error
NoMethodError (undefined method `[]' for nil:NilClass):
app/controllers/top_controller.rb:173:in `test_action'
How can I solve this? These are my codes
gems related that are already bundled (I'm on rails 3.2.11)
gem 'omniauth-twitter'
gem 'twitter'
gem 'figaro'
config/initializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET']
Twitter.configure do |config|
config.consumer_key = ENV["TWITTER_KEY"]
config.consumer_secret = ENV["TWITTER_SECRET"]
end
end
config/application.yml
TWITTER_KEY: 6TeBX6HkeHzMXesgc
TWITTER_SECRET: JyfOndg8xHcM81KEpgmBT7h2vFJJujMP14YTdt6ruvLbsQk
test_action
def test_action
#twitter = Twitter::Client.new(oauth_token: request.env["omniauth.auth"][:credentials][:token], oauth_token_secret: request.env["omniauth.auth"][:credentials][:secret])
#twitter.update("Your message")
flash[:notice] = "Successfully tweeted on your account."
redirect_to root_path
return
end
I think your issue may be with your controller configuration of Twitter:
instead of:
#twitter = Twitter::Client.new(oauth_token: request.env["omniauth.auth"][:credentials][:token], oauth_token_secret: request.env["omniauth.auth"][:credentials][:secret])
try this:
#twitter = Twitter::REST::Client.new do |config|
config.consumer_key = ENV['CONSUMER_KEY']
config.consumer_secret = ENV['CONSUMER_SECRET']
config.access_token = request.env["omniauth.auth"][:credentials][:token]
config.access_token_secret = request.env["omniauth.auth"][:credentials][:secret]
end
You also might want to confirm that your API keys have read and write permissions, which you can check on your Twitter developer account here.

Rails: Twitter Omniauth gem 401 Unauthorized Error

I am using twitter omniauth gem in my web application. I stored my key and secret in my DB.
This is my middleware code
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter, lambda { Site.config[:twitter][:key] },lambda{ Site.config[:twitter][:secret] }
end
This returns unauthorized error.
But when i specify my key and secret directly in the middleware it works.
(i.e)
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter, "consumer_key" , "consumer_secret"
end
What is wrong with my first approach ?
You need to use Setup Phase
provider :twitter, :setup => true
And then in controller:
def setup
request.env['omniauth.strategy'].options[:consumer_key] = Site.config[:twitter][:key]
request.env['omniauth.strategy'].options[:consumer_secret] = Site.config[:twitter][:secret]
render :text => "Setup complete.", :status => 404
end
Routes:
match '/auth/:provider/setup' => 'sessions#setup' # for example
You can add your consumer_key and consumer secret in the development.rb and production.rb
# twitter api credential
config.twitt_consumer_key = 'xxxxxxxxxxxxxxxxx'
config.twitt_consumer_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
And then you can use it
provider :twitter, Rails.application.config.twitt_consumer_key, Rails.application.config.twitt_consumer_secret

Omniauth-Facebook callback does not get initialised in Rails Mountable Engine

I'm developing a mountable engine (called SimpleUser) which uses Devise, OmniAuth and OmniAuth-Facebook. First I made a test app with the gems about and every worked fine. Next, I started building the engine from scratch, using the code of the test app as an example.
Everything is almost done, except for the connection with Facebook (it uses the Javascript popup). When I click in "log in" the FB popup is displayed, I grant the app, it redirects to the route specified (see routes), but throws this error:
NoMethodError in SimpleUser::AuthController#create
undefined method `[]' for nil:NilClass
The error occurs in that action, in the line authentication = Authentication.find_by_provider_and_uid(auth['provider'], auth['uid']) where auth is nil (auth comes from auth = request.env["omniauth.auth"]).
One thing I check is that the Callback phase it's no initialised. This is the log of the test app:
Started GET "/auth/facebook/callback" for 127.0.0.1 at 2013-03-14
08:52:56 -0600 (facebook) Callback phase initiated. Processing by
AuthController#create as HTML Parameters: {"provider"=>"facebook"}
This is the log of the engine app:
Started GET "/simple_user/auth/facebook/callback" for 127.0.0.1 at 2013-03-14 08:51:19 -0600
Processing by SimpleUser::AuthController#create as HTML
Parameters: {"provider"=>"facebook"}
For manage OmniAuth, I added the gem to the .gemspec and to the Gemfile; also, I require the gems in the engine, and within a generator of the engine I move a template of omniauth.rb to config/initializers of the parent app during installation. This is what I have:
AuthController (located in app/controllers/simple_user/auth_controller.rb)
module SimpleUser
class AuthController < ApplicationController
def create
auth = request.env["omniauth.auth"]
authentication = Authentication.find_by_provider_and_uid(auth['provider'], auth['uid'])
if authentication
flash[:notice] = "Signed in successfully."
sign_in(:user, authentication.user)
redirect_to root_url
else
user = User.build_new_auth(auth)
#user.apply_omniauth(auth)
if user.save(:validate => false)
flash[:notice] = "Account created and signed in successfully."
sign_in(:user, user)
redirect_to root_url
else
flash[:error] = "Error while creating the user account. Please try again."
redirect_to root_url
end
end
end
end
end
Engine
module SimpleUser
require 'rubygems'
require 'devise'
require 'cancan'
require 'rolify'
require 'omniauth'
require 'omniauth-facebook'
require 'simple_form'
class Engine < ::Rails::Engine
isolate_namespace SimpleUser
config.before_configuration do
env_file = File.join(Rails.root, 'config', 'fb_config.yml')
YAML.load(File.open(env_file)).each do |key, value|
ENV[key.to_s] = value.to_s
end if File.exists?(env_file)
env_file = File.join(Rails.root, 'config', 'devise_config.yml')
YAML.load(File.open(env_file)).each do |key, value|
ENV[key.to_s] = value.to_s
end if File.exists?(env_file)
end
end
end
Generator
module SimpleUser
module Generators
class InstallGenerator < ::Rails::Generators::Base
source_root File.expand_path("../templates", __FILE__)
desc "Install SimpleUser"
def copy_config_file
copy_file "fb_config.yml", "config/fb_config.yml"
copy_file "devise_config.yml", "config/devise_config.yml"
copy_file "omniauth.rb", "config/initializers/omniauth.rb"
end
def copy_migrations
rake "simple_user:install:migrations"
SimpleUser::Engine.load_seed
end
end
end
end
Template of the omniauth.rb
require 'omniauth'
require 'omniauth-facebook'
OmniAuth.config.logger = Rails.logger
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'], :scope => ENV['FACEBOOK_SCOPE']
end
Routes (on engine)
match 'auth/:provider/callback', to: 'auth#create'
match 'auth/failure', to: redirect('/')
Routes (on dummy app)
mount SimpleUser::Engine => "/simple_user", :as => "simple_user"
.gemspec dependencies
s.add_dependency "rails", "~> 3.2.12"
s.add_dependency "devise"
s.add_dependency "cancan"
s.add_dependency "rolify"
s.add_dependency "omniauth"
s.add_dependency "omniauth-facebook", "1.4.1"
s.add_dependency "simple_form"
#s.add_development_dependency "mysql2"
s.add_development_dependency "sqlite3"
s.add_development_dependency "jquery-rails"
s.add_development_dependency "debugger"
Gemfile
source "http://rubygems.org"
gemspec
gem 'devise'
gem 'cancan'
gem 'rolify'
gem 'omniauth'
gem 'omniauth-facebook', '1.4.1'
gem 'simple_form'
# Development
gem 'jquery-rails'
gem 'debugger'
I think the problem is the callback that is not initialised, and the reason may be that OmniAuth doesn't get loaded, but I don't know if it is and how to solve it.
You can check the project in https://github.com/pablomarti/simple_user, and if you want to clone it and test you can use the generator rails g simple_user:install, and you can see the code of test/dummy also to get the idea.
Thank you very much in advance.
The solution was to remove the omniauth.rb and include the middleware of OmniAuth in the engine, so the engine looks like this:
module SimpleUser
require 'rubygems'
require 'devise'
require 'cancan'
require 'rolify'
require 'omniauth'
require 'omniauth-facebook'
require 'simple_form'
class Engine < ::Rails::Engine
isolate_namespace SimpleUser
middleware.use OmniAuth::Builder do
provider :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'], :scope => ENV['FACEBOOK_SCOPE']
end
config.before_configuration do
env_file = File.join(Rails.root, 'config', 'fb_config.yml')
YAML.load(File.open(env_file)).each do |key, value|
ENV[key.to_s] = value.to_s
end if File.exists?(env_file)
env_file = File.join(Rails.root, 'config', 'devise_config.yml')
YAML.load(File.open(env_file)).each do |key, value|
ENV[key.to_s] = value.to_s
end if File.exists?(env_file)
end
end
end
Thanks to Dmitry Lihachev for his answer https://stackoverflow.com/a/8413724/347501 in a similar problem.

Resources