I am using omniauth-facebook gem to authorize using facebook in my rails application.
I have followed these instructions but the problem I am facing is error about invalid credentials:
(facebook) Authentication failure! invalid_credentials: OAuth2::Error, :
{"error":{"message":"Error validating application. Invalid application ID.","type":"OAuthException","code":101}}
What is weird about this is that I am getting user info even though I get this error from facebook api.
the value of request.env['omniauth.auth']
is(server log).
#<OmniAuth::AuthHash credentials=#<OmniAuth::AuthHash expires=true
expires_at=1421256863 token="some_long_value"> extra=#<OmniAuth::AuthHash
raw_info=#<OmniAuth::AuthHash education=[#<OmniAuth::AuthHash school=
#<OmniAuth::AuthHash id="174179219354091" name="Udacity"> type="College">]
email="ashish#gmail.com" favorite_athletes=[#<OmniAuth::AuthHash id="51926382304"
name="Derrick Rose">, #<OmniAuth::AuthHash id="344128252278047" name="Sachin
Tendulkar">,.... so on
routes.rb
devise_for :users, :controllers => {:omniauth_callbacks => "omniauth_callbacks"}
config/initializers/omniauth.rb
OmniAuth.config.logger = Rails.logger
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, 'key', 'secret', {:provider_ignores_state => true}
# key and secret are correctly added in above line
end
app/model/user.rb
devise :omniauthable, :omniauth_providers => [:facebook]
app/controller/omniauth_callback_controller.rb
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
omniauth = request.env['omniauth.auth']
# Other code to create authentication and other logic
puts "===>>> Omniauth is #{omniauth}"
end
def failure
res = request.env['omniauth.auth']
puts "======>>>>>> Authentication failed #{res}"
redirect_to root_path
end
end
Every time response goes to failure method but not to facebook method.
What I don't understand is when I am getting invalid credentials error from api then how come I get all the data from facebook. I doubt I have something wrong on my end while handling the callback from facebook.
Can anyone point where the problem can be?
I am pretty sure I am using correct application id and key I am getting data from facebook in the response.
Can anybody help me with this issue?
Related
OK i'm not really a ROR person but I'm trying to modify an existing app (forked) from https://github.com/adamcooke/staytus
there's an /admin page which right now brings you to a haml login form with a username/password box.
What I'm attempting to do us change this functionally so that when /admin is hit devise and omniAuth will redirect to my IDP via OpenIDConnect ask the user to login with their creds, do the auth stuff and pending they get through then show the admin section...
here's what I've done thus far:
installed these gems
gem 'devise'
gem 'omniauth-rails_csrf_protection'
gem 'omniauth-azure-activedirectory-v2'
ran the devise config/install:
added config.rb
def omniauth_oidc?
result = ENV['OMNIAUTH_OIDC'] == '1'
puts "omniauth_oidc? result: #{result}"
I've tried all combinations of routes:
devise_scope :user do
devise_for :users, controllers: { omniauth_callbacks: 'admin/omniauth_callbacks' }
end
devise_scope :user do
get '/admin/omniauth_callbacks' => 'admin/omniauth_callbacks#azure_activedirectory_v2'
end
namespace :admin do
get '/omniauth_callbacks', to: 'omniauth_callbacks#azure_activedirectory_v2'
end
result
end
I've also tried " to: 'sessions#create'" routes but clearly I'm missing something here...
added OmniauthCallbacksControler
class Admin::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def azure_activedirectory_v2
puts "request.env['omniauth.auth']: #{request.env['omniauth.auth'].inspect}"
response_params = request.env['omniauth.auth']
if response_params.nil?
Rails.logger.error("request.env['omniauth.auth'] is nil")
raise "request.env['omniauth.auth'] is nil"
else
response_params = response_params['info']
end
#user = User.find_by!(email: response_params['email'])
if #user&.persisted?
sign_in_and_redirect #user, event: :authentication, location: admin_root_path
else
flash[:danger] = 'You have not yet an account!'
redirect_back(fallback_location: admin_root_path)
end
end
end
added omniauth.rb initializer
Rails.application.config.middleware.use OmniAuth::Builder do
provider :developer if Rails.env.development?
provider :azure_activedirectory_v2,
{
client_id: ENV[''],
client_secret: ENV[''],
tenant_id: ENV[']
}
end
given all of the above I still haven't gotten /admin to redirect to my IDP login ? WHY ?
I've had an instagram omniauth integration working now for a few years and I haven't changed anything in a long time but my customers are occasionally out of the blue getting an error when connecting their Instagram accounts:
Started GET "/auth/instagram/callback?code=d3b1c4d88e2f440b8a8a98037b821c15&state=2565d32ecd3cc5967f32d8c945db6ffba74dc784100777f2" for 127.0.0.1 at 2016-12-15 15:29:59 -
0800
I, [2016-12-15T15:29:59.276712 #32520] INFO -- omniauth: (instagram) Callback phase initiated.
E, [2016-12-15T15:29:59.519801 #32520] ERROR -- omniauth: (instagram) Authentication failure! invalid_credentials: OAuth2::Error, :
{"code": 400, "error_type": "OAuthException", "error_message": "Matching code was not found or was already used."}
The only way I can consistently get this to happen is to connect the account from my app, then remove permissions from the instagram end, then try to reconnect again on my app, but it seems like some of my customers are getting this the first time they connect their instagram accounts.
Anyone encountered this before? My config/initializers/omniauth.rb looks like this:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :instagram, ENV['INSTAGRAM_CLIENT_ID'], ENV['INSTAGRAM_CLIENT_SECRET'], scope: 'basic comments public_content'
end
Edit:
I'm using omniauth 1.3.1 and omniauth-instagram 1.0.2
My routes is just your basic omniauth route:
get '/auth/:provider/callback', to: 'omniauth_callbacks#create'
And my controller action is a bit complex but it looks like this:
class OmniauthCallbacksController < ApplicationController
def create
if user_signed_in?
social_account = SocialAccount.from_omniauth(auth_params, current_user)
social_account.save!
redirect_to root_path
else
user = User.from_omniauth auth_params
sign_in_and_redirect user
end
end
private
def auth
request.env['omniauth.auth']
end
def auth_params
{
provider: auth['provider'],
uid: auth['uid'],
token: auth['credentials']['token'],
secret: auth['credentials']['secret'] || auth['credentials']['refresh_token'],
name: auth['info']['nickname'] || auth['info']['name'],
emails_sent: 0
}
end
end
Basically it creates a new user and signs them in if they haven't connected, and it updates their login info if they have.
There seems to be a problem on Instagram around getting access tokens. https://news.ycombinator.com/item?id=13178789
I followed this railcasts tutorial on how to implement Omniauth-identity but hit a snag.
When I try to register the user the following error pops up
ActionController::InvalidAuthenticityToken in SessionsController#create
In the console logs the following error pops up
Processing by SessionsController#create as HTML
Parameters: {"name"=>"asdasd asdasd", "email"=>"asd#yopmail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "provider"=>"identity"}
Can't verify CSRF token authenticity
The user is inserted in the Identity model without problems but when the application tries to create a session it is all for naught.
Here is the relevant code I am using
Gemfile
OpenID Authentication
gem 'bcrypt-ruby', '~> 3.1.2'
gem 'omniauth-facebook'
gem 'omniauth-twitter'
gem 'omniauth-google-oauth2'
gem 'omniauth-identity'
initializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, ENV['FACEBOOK_APP_ID'], ENV['FACEBOOK_SECRET']
provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET']
provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET']
provider :identity
end
routes
get 'auth/:provider/callback', to: 'sessions#create'
post 'auth/:provider/callback', to: 'sessions#create'
get 'auth/failure', to: redirect('/')
get 'signout', to: 'sessions#destroy', as: 'signout'
SessionsController
def create
user = User.from_omniauth(env['omniauth.auth'])
session[:user_id] = user.id
redirect_to root_url, notice: "Signed In!"
end
Users model
def self.from_omniauth(auth)
find_by_provider_and_uid(auth["provider"], auth["uid"]) || create_with_omniauth(auth)
end
The error InvalidAuthenticityToken raised when Rails check the CSRF token, you can disable CSRF protection on controller by skipping the verification skip_before_action, add to the top of your SessionsController:
skip_before_action :verify_authenticity_token, only: :create
But you must be careful and read all about the CSRF protection.
This solved my problem.
Quoting as it is from the source:
I just spent quite some time debugging this. In my case, I was following an auth0 tutorial that instructed to generate a link with <%= button_to "Login", "auth/auth0", method: :post %>. I was banging my head to a wall for a long time because of the InvalidAuthenticityToken exception.
Turns out that the path had to be "/auth/auth0" (slash in the beginning) for rails to correctly compare the path. Shrug. Maybe this helps someone else. Not sure if this is actually a Rails bug.. it seems at least little unfriendly.
So I'm using Omniauth to authenticate with the likes of Twitter and Foursquare. Twitter works fine, but Foursquare doesn't appear to return a secret.
Anyone know what's going wrong?
Here's the create action in the controller, Foursquare is passing the user back to this, but as I said, it's not getting the secret, just the token
def create
omniauth = request.env["omniauth.auth"]
unless current_user.authentications.find_by_provider_and_uid(omniauth['provider'], omniauth['uid'])
current_user.apply_omniauth(omniauth)
current_user.save
end
flash[:notice] = "Authentication Successfull"
redirect_to authentications_url
end
Here is the apply omniauth method:
def apply_omniauth(omniauth)
authentications.build(
:provider => omniauth['provider'],
:uid => omniauth['uid'],
:token => omniauth['credentials']['token'],
:secret => omniauth['credentials']['secret']
)
end
Foursquare should not pass back a secret, just the token. The foursquare api key and and secret are provided to you by foursquare when you register your app on their developers site. You must use these values in your omniauth.rb
Twitter uses Oauth 1.0 and foursquare uses 2.0
That could be your issue there
I am using Rails 3.
I am getting a Rack::OAuth2::Client::Error in SessionsController#create error when I try to get the access key.
I used omniauth to login to facebook and I am getting the param["code"]
Now I try to use fbgraph to get the access code and I am getting the Rac::OAuth2::Client::Error.
def create
auth=request.env["omniauth.auth"]
fb_auth=FbGraph::Auth.new("xxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxx")
client=fb_auth.client
client.redirect_uri="http://localhost:3000/facebook/callback/"
client.authorization_code=params[:code]
access_token = client.access_token! # => Rack::OAuth2::AccessToken
user=User.find_by_provider_and_uid(auth["provider"], auth["id"]) ||User.create_with_omniauth(auth, access_token)
session[:user_id]=user.id
redirect_to root_url, :notice => "Signed In!"
end
The access_token! line is what is returning the error.
If you set the redirect_uri on the fb_auth instead of the client it should be fine e.g.
fb_auth = FbGraph::Auth.new(
"xxxxxxx",
"xxxxxxxxxxxxxxxxxxxxxxxxxxx",
:redirect_uri = "http://localhost:3000/facebook/callback"
)
client=fb_auth.client
client.authorization_code=params[:code]
access_token = client.access_token! # => Rack::OAuth2::AccessToken
You should also check out https://github.com/nov/fb_graph/issues/127#issuecomment-2244499,
then have a read of the fb_graph_sample code and setup your FbGraph debugging.