Omniauth-twitter returns 401 - oauth

Stage:
I have a Rails app, it should authenticate users using their twitter account, so I use Omniauth-Twitter gem.
I have configured one app in dev.twitter.com enabling Sign in with twitter flag and getting consumer_key and consumer_secret.
I was following this guide https://github.com/arunagw/omniauth-twitter#readme
In Rails app, I have configured some files:
config/initializers/omniauth.rb:
Rails.application.config.middleware.use OmniAuth::Builder do
# Twitter consumer data
CONSUMER_KEY='xxxxxxxxxxxxxxxxx'
CONSUMER_SECRET='yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'
provider :twitter, CONSUMER_KEY, CONSUMER_SECRET
end
sessions_controller.rb looks like:
class SessionsController < ApplicationController
def create
raise request.env["omniauth.auth"].to_yaml
end
end
applications.html.erb layout:
<div id="user_nav">
<%= link_to "Sign in with Twitter", "/auth/twitter" %>
</div>
So I except that when I clic on Sign in with Twitter link, I raises an exception showing me authentication data or requesting me Twitter autorization.
Problem:
Instead of this, it returns back this:
OAuth::Unauthorized (401 Unauthorized):
oauth (0.4.7) lib/oauth/consumer.rb:216:in `token_request'
oauth (0.4.7) lib/oauth/consumer.rb:136:in `get_request_token'
omniauth-oauth (1.0.1) lib/omniauth/strategies/oauth.rb:29:in `request_phase'
omniauth-twitter (0.0.15) lib/omniauth/strategies/twitter.rb:63:in `request_phase'
omniauth (1.1.3) lib/omniauth/strategy.rb:207:in `request_call'
omniauth (1.1.3) lib/omniauth/strategy.rb:174:in `call!'
omniauth (1.1.3) lib/omniauth/strategy.rb:157:in `call'
omniauth (1.1.3) lib/omniauth/builder.rb:48:in `call'
What is wrong here?

Related

invalid_client oauth2 error after authorizing my rails app

I'm trying to authenticate against an Oauth2 provider using Rails 4.1. After being redirected to the authorize/deny prompt, and clicking authorize, I'm redirected to my callback url and encounter the following error:
Started GET "/auth/</callback?code=<code>&state=<state>" for 127.0.0.1 at 2014-08-25 12:47:57 +0200
I, [2014-08-25T12:47:57.981471 #12769] INFO -- omniauth: (<provider>) Callback phase initiated.
E, [2014-08-25T12:47:58.697527 #12769] ERROR -- omniauth: (<provider>) Authentication failure! invalid_credentials: OAuth2::Error, invalid_client: Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.
{"error":"invalid_client","error_description":"Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method."}
OAuth2::Error (invalid_client: Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.
{"error":"invalid_client","error_description":"Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method."}):
oauth2 (0.9.4) lib/oauth2/client.rb:113:in `request'
oauth2 (0.9.4) lib/oauth2/client.rb:138:in `get_token'
oauth2 (0.9.4) lib/oauth2/strategy/auth_code.rb:29:in `get_token'
omniauth-oauth2 (1.1.2) lib/omniauth/strategies/oauth2.rb:93:in `build_access_token'
omniauth-oauth2 (1.1.2) lib/omniauth/strategies/oauth2.rb:75:in `callback_phase'
omniauth (1.2.2) lib/omniauth/strategy.rb:227:in `callback_call'
omniauth (1.2.2) lib/omniauth/strategy.rb:184:in `call!'
omniauth (1.2.2) lib/omniauth/strategy.rb:164:in `call'
omniauth (1.2.2) lib/omniauth/builder.rb:59:in `call'
rack (1.5.2) lib/rack/etag.rb:23:in `call'
rack (1.5.2) lib/rack/conditionalget.rb:25:in `call'
The error is thrown by the oauth2 gem, and it never reaches my /auth/failure endpoint while in development. My routes.rb is as follows
Rails.application.routes.draw do
root 'static_pages#home'
# Auth routes
get '/auth/:provider/callback', to: 'sessions#create'
get '/signin', to: 'sessions#new', as: :signin
get '/signout', to: 'sessions#destroy', as: :signout
get '/auth/failure', to: 'sessions#failure'
end
My sessions controller is just an skeleton, but it never gets there as I said before:
class SessionsController < ApplicationController
def new
redirect_to '/auth/<provider>'
end
def create
redirect_to root_url, notice: 'Signed in'
end
def destroy
redirect_to root_url, notice: 'Signed out'
end
def failure
redirect_to root_url, alert: "Oops: #{params[:messsage].humanize}"
end
end
I'm certain that the ID and secret keys I use work (they work using this tool https://www.runscope.com/oauth2_tool). Im using the following strategy, implemented by the Oauth provider:
module OmniAuth
module Strategies
class <Provider> < OmniAuth::Strategies::OAuth2
# Give your strategy a name.
option :name, '<provider_name>'
option :provider_ignores_state, true
# This is where you pass the options you would pass when
# initializing your consumer from the OAuth gem.
option :client_options, {
site: 'https://<provider>/api/3',
authorize_url: 'https://<provider>/oauth2/authorize',
token_url: 'https://<provider>/oauth2/token'
}
option :authorize_params, {
response_type: 'code'
}
# These are called after authentication has succeeded. If
# possible, you should try to set the UID without making
# additional calls (if the user id is returned with the token
# or as a URI parameter). This may not be possible with all
# providers.
uid{ raw_info['id'] }
info do
{
:name => [ raw_info['first_name'], raw_info['last_name'] ].join(' '),
:email => raw_info['email']
}
end
extra do
{
'raw_info' => raw_info
}
end
def raw_info
#raw_info ||= access_token.get("#{options[:client_options][:site]}/me").parsed
end
end
end
end
I suspect that it is not sending a proper request for an access_token, but I haven't managed to diagnose it yet. Any help would be appreciated.

Devise omniauthable breaks Omniauth authentication with `Could not find a valid mapping for path`

In my project, I have two type of users: job seekers and hiring managers. Job seekers don't have a model, they are just able to apply for jobs using the data received from from third-party providers while authenticating thru Omniauth. Hiring managers' info is stored in devise User model. Hiring managers also must be able to sign in with their company's Google email account.
So, first I built job seekers' authentication using Omniauth 1.0.0, Rails 3.1.3:
omniauth.rb
require 'omniauth-openid'
require 'openid/store/filesystem'
Rails.application.config.middleware.use OmniAuth::Builder do
provider :openid, :store => OpenID::Store::Filesystem.new('./tmp'), :name => 'google', :identifier => 'https://www.google.com/accounts/o8/id'
provider :facebook, "xxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
{:scope => 'email, offline_access, publish_stream', :client_options => {:ssl => {:ca_file => '/usr/lib/ssl/certs/ca-certificates.crt'}}}
provider :twitter, "xxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
provider :linkedin, "xxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxx"
end
in routes.rb:
match '/auth/:provider/callback', :to => 'sessions#authenticate_jobseeker'
match '/auth/failure', :to => 'sessions#failure'
in sessions_controller.rb
def authenticate_jobseeker
session[:jobseeker] = request.env['omniauth.auth']
if valid_job_seeker?
redirect_to new_job_application_path(...)
else
redirect_to request.env['omniauth.origin'] || root_path, alert: "Authentication failure"
end
end
Up to this point everything worked fine. However, when I started implementing Google sign on for User model, and added :omniauthable to it, my job seeker authentication broke. I am using Devise 1.5.2:
user.rb
class User < ActiveRecord::Base
#...
devise :database_authenticatable, :registerable,
... :lockable, :omniauthable
#...
end
in devise.rb:
config.omniauth :open_id, :store => OpenID::Store::Filesystem.new('./tmp'), :name => 'google', :identifier => 'https://www.google.com/accounts/o8/id', :require => 'omniauth-openid'
in routes.rb:
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" } do
get '/users/auth/:provider' => 'users/omniauth_callbacks#passthru'
end
At this point, Users' authentication worked, but job seekers' did not. After searching for a while, the issue was fixed by adding :path_prefix => "/auth" to every provider in omniauth.rb.
The only problem now, is when job seeker does not allow access to its data (i.e. presses "Don't Allow" and comes back to the application), I get following RuntimeError for every provider:
Could not find a valid mapping for path "/auth/twitter/callback"
Parameters:
{"denied"=>"mKjVfMRwRAN12ZxQ9cxCoD4rYSLJIRLnEqgiI"}
top of the trace:
devise (1.5.2) lib/devise/mapping.rb:48:in `find_by_path!'
devise (1.5.2) lib/devise/omniauth.rb:17:in `block in <top (required)>'
omniauth (1.0.0) lib/omniauth/strategy.rb:418:in `call'
omniauth (1.0.0) lib/omniauth/strategy.rb:418:in `fail!'
omniauth-oauth (1.0.0) lib/omniauth/strategies/oauth.rb:63:in `rescue in callback_phase'
omniauth-oauth (1.0.0) lib/omniauth/strategies/oauth.rb:45:in `callback_phase'
omniauth (1.0.0) lib/omniauth/strategy.rb:200:in `callback_call'
omniauth (1.0.0) lib/omniauth/strategy.rb:166:in `call!'
omniauth (1.0.0) lib/omniauth/strategy.rb:148:in `call'
omniauth (1.0.0) lib/omniauth/strategy.rb:168:in `call!'
omniauth (1.0.0) lib/omniauth/strategy.rb:148:in `call'
omniauth (1.0.0) lib/omniauth/strategy.rb:168:in `call!'
omniauth (1.0.0) lib/omniauth/strategy.rb:148:in `call'
omniauth (1.0.0) lib/omniauth/builder.rb:30:in `call'
I've been trying to solve it for a while now. Any help is greatly appreciated. Let me know, if I can provide additional info.
Answering my own question. So, final decision was to go with pure Omniauth implementation. I removed :omniauthable from User model, removed config.omniauth... from devise.rb, removed :omniauth_callbacks devise routes from routes.rb.
So, all users (no matter what role) would use ame callback routes and hit sessions_controller#authenticate_jobseeker action (should consider renaming the action?):
def authenticate_jobseeker
auth_hash = request.env['omniauth.auth']
unless auth_hash.present?
redirect_to request.env['omniauth.origin'] || root_path, alert: "Sorry, we were not able to authenticate you" and return
end
#user = User.find_from_oauth(auth_hash)
if #user.present?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Google"
sign_in_and_redirect #user, :event => :authentication and return
else
session[:jobseeker] = auth_hash["info"]
if valid_job_seeker?
redirect_to new_job_application_path(...)
end
end
end
and User.find_from_oauth:
def self.find_from_oauth(auth_hash)
if auth_hash
user = User.where(:email => auth_hash["info"]["email"]).first
end
user
end
This implementation satisfied all of the requirements.
Are you using omniauth["user_info"] in your models somewhere? In my case, I was accessing
omniauth["user_info"]["email"]
and that would crash and I would get the same error, being caught by devise.
In my app as well, we use omniauth directly (for businesses) as well as use device+facebook for user logins.
Havent yet figured out to not get failure caught by devise though. Devise registers it's own failure app. Will update when i figure it out.
Update: I'm sorry it seems I misread part of your question. You can see a clear failure to authorize from the remote webapp which seems to stuff up and not a masked exception from the code (as was in my case).

Failing "layout_links_spec" integration tests during Ruby on Rails Tutorial

I am following the Ruby on Rails Tutorial for Rails 3, located here:
http://ruby.railstutorial.org
I am at this section of the tutorial:
http://ruby.railstutorial.org/chapters/filling-in-the-layout#sec:integration_tests
All of my pages render as expected at this point; e.g., I can hit http://localhost:3000/about and see the about page of the sample application, with the expected title ("Ruby on Rails Tutorial Sample App | About"). Yet the integration tests from this section keep failing.
Here is my layout_links_spec.rb:
require 'spec_helper'
describe "LayoutLinks" do
it "should have a Home page at '/'" do
get '/'
response should have_selector('title', :content => "Home")
end
it "should have a Contact page at '/contact'" do
get '/contact'
response should have_selector('title', :content => "Contact")
end
it "should have an About page at '/about'" do
get '/about'
response should have_selector('title', :content => "About")
end
it "should have a Help page at '/help'" do
get '/help'
response should have_selector('title', :content => "Help")
end
end
When I run tests with rspec spec/ or via autotest, I get the following test failures:
........FFFF
Failures:
1) LayoutLinks should have a Home page at '/'
Failure/Error: response should have_selector('title', :content => "Home")
expected following output to contain a <title>Home</title> tag:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><p>LayoutLinks</p></body></html>
# ./spec/requests/layout_links_spec.rb:7:in `block (2 levels) in <top (required)>'
2) LayoutLinks should have a Contact page at '/contact'
Failure/Error: response should have_selector('title', :content => "Contact")
expected following output to contain a <title>Contact</title> tag:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><p>LayoutLinks</p></body></html>
# ./spec/requests/layout_links_spec.rb:12:in `block (2 levels) in <top (required)>'
3) LayoutLinks should have an About page at '/about'
Failure/Error: response should have_selector('title', :content => "About")
expected following output to contain a <title>About</title> tag:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><p>LayoutLinks</p></body></html>
# ./spec/requests/layout_links_spec.rb:17:in `block (2 levels) in <top (required)>'
4) LayoutLinks should have a Help page at '/help'
Failure/Error: response should have_selector('title', :content => "Help")
expected following output to contain a <title>Help</title> tag:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><p>LayoutLinks</p></body></html>
# ./spec/requests/layout_links_spec.rb:22:in `block (2 levels) in <top (required)>'
Finished in 0.23497 seconds
12 examples, 4 failures
Failed examples:
rspec ./spec/requests/layout_links_spec.rb:5 # LayoutLinks should have a Home page at '/'
rspec ./spec/requests/layout_links_spec.rb:10 # LayoutLinks should have a Contact page at '/contact'
rspec ./spec/requests/layout_links_spec.rb:15 # LayoutLinks should have an About page at '/about'
rspec ./spec/requests/layout_links_spec.rb:20 # LayoutLinks should have a Help page at '/help'
...note that the response shown in the test failures appears to indicate that I'm getting a mock/stubbed response. I believe that this is my issue, but I don't know why it is happening.
Finally, here is my environment:
Gatito:sample_app abrown$ gem list
*** LOCAL GEMS ***
abstract (1.0.0)
actionmailer (3.0.9)
actionpack (3.0.9)
activemodel (3.0.9)
activerecord (3.0.9)
activeresource (3.0.9)
activesupport (3.0.9)
arel (2.0.10)
autotest (4.4.6)
autotest-fsevent (0.2.4)
autotest-growl (0.2.9)
autotest-rails-pure (4.1.2)
builder (2.1.2)
bundler (1.0.15)
configuration (1.2.0)
diff-lcs (1.1.2)
erubis (2.6.6)
heroku (2.3.3)
i18n (0.5.0)
launchy (0.4.0)
mail (2.2.19)
mime-types (1.16)
nokogiri (1.4.6)
polyglot (0.3.1)
rack (1.2.3)
rack-mount (0.6.14)
rack-test (0.5.7)
rails (3.0.9)
railties (3.0.9)
rake (0.9.2, 0.8.7)
rdoc (3.6.1)
rest-client (1.6.3)
rspec (2.6.0)
rspec-core (2.6.4)
rspec-expectations (2.6.0)
rspec-mocks (2.6.0)
rspec-rails (2.6.1)
sequel (3.20.0)
sinatra (1.0)
spork (0.9.0.rc8)
sqlite3 (1.3.3)
sqlite3-ruby (1.3.3)
sys-uname (0.8.5)
taps (0.3.23)
term-ansicolor (1.0.5)
thor (0.14.6)
treetop (1.4.9)
tzinfo (0.3.28)
webrat (0.7.1)
ZenTest (4.5.0)
I figured it out. I typed in the tests above myself. When I re-copied/pasted the tests directly from the tutorial, they began passing. I was mystified, as everything looked identical at a glance. But after running a diff, I realized that for each test, I had typed:
response should
...but that I should have typed:
# Note the "."
response.should
After making this correction to each test, they all pass as expected.
I've experienced the exact same error, but the cause was forgetting to include render_views line in the test:
require 'spec_helper'
describe PagesController do
render_views
describe "GET 'home'" do
it "should be successful" do
get 'home'
response.should be_success
end
end

Problem when migrating from Authlogic to Devise

I referred this Migrating from Authlogic to Devise
and followed it to get the database structure required by devise ready.
However I get this error on my sign_in page
wrong number of arguments (2 for 1)
This is my Request:
{"commit"=>"Sign in","authenticity_token"=>"oWXrE+EdhO4ScuaBzPBqCnpYsal1QcDC483ygVSs0fw=","user"=>{"password"=>"password", "email"=>"email#email.com"}}
I'm using Rails 2.3.8 and hence using Devise v 1.0.
This is my sessions/new view :
<% form_for resource_name, resource, :url => session_path(resource_name) do |f| -%>
<p><%= f.label :email %></p>
<p><%= f.text_field :email %></p>
<p><%= f.label :password %></p>
<p><%= f.password_field :password %></p>
<p><%= f.submit "Sign in" %></p>
<% end -%>
Any ideas to get this to work? Thanks !
EDIT
Here's the stack trace:
ArgumentError (wrong number of arguments (2 for 1)):
devise (1.0.8) lib/devise/models/database_authenticatable.rb:139:in `find_for_authentication'
devise (1.0.8) lib/devise/models/database_authenticatable.rb:117:in `authenticate'
devise (1.0.8) lib/devise/strategies/database_authenticatable.rb:16:in `authenticate!'
warden (1.0.3) lib/warden/strategies/base.rb:53:in `_run!'
warden (1.0.3) lib/warden/proxy.rb:303:in `_run_strategies_for'
warden (1.0.3) lib/warden/proxy.rb:298:in `each'
warden (1.0.3) lib/warden/proxy.rb:298:in `_run_strategies_for'
warden (1.0.3) lib/warden/proxy.rb:271:in `_perform_authentication'
warden (1.0.3) lib/warden/proxy.rb:90:in `authenticate'
devise (1.0.8) lib/devise/controllers/helpers.rb:36:in `authenticate'
devise (1.0.8) app/controllers/sessions_controller.rb:19:in `create'
warden (1.0.3) lib/warden/manager.rb:35:in `call'
warden (1.0.3) lib/warden/manager.rb:34:in `catch'
warden (1.0.3) lib/warden/manager.rb:34:in `call'
Anything to do with warden dependency?
I had the same problem, using warden 0.10.7 and devise 1.0.8
I tried the User.find in the console and was OK.
To fix it, I removed the class method authenticate on my User-Model:
#def self.authenticate(login, pass)
# find(:first, :conditions => ["login = ? AND password = ?", login, sha1(pass)])
#end
The error seems to be occuring in a User.find call, which is strange. Do you have anything that might be overriding the default find method?
Try this in the console and see if you get an error.
User.find(:first, :conditions=>{:email=>'email#email.com'})

authlogic flash[:notice] does not show up in cucumber webrat step

I am running BDD steps with cucumber to implement my autlogic login behavior.
Scenario: log in
Given a registered user: "test#test.com" with password: "p#ssword" exists
And I am on the homepage
When I follow "Log in"
And I fill in "Username" with "test#test.com"
And I fill in "Password" with "p#ssword"
And I open the page
And I press "Login"
And I open the page
Then I should see "Login successful!"
And I should see "Logout"
this is my scenario and when I hit
Then I should see "Login successful!"
my cucumber step fails but only in webrat. I debugged with launchy and when the web-page appeard there is indeed no message but in development mode, when I run script/server I see my messages.
My controller looks like this
def create
#user_session = UserSession.new(params[:user_session])
if #user_session.save
flash[:notice] = "Login successful!"
redirect_to root_url
else
render :action => 'new'
end
end
And yes I saw this
http://github.com/binarylogic/authlogic/issuesearch?state=open&q=cucumber+flash#issue/142
and did not understand how this could help me
and this also did not help
Rails/Cucumber/Webrat: redirect_to, flash[:notice] not working
my setup is
*** LOCAL GEMS ***
actionmailer (2.3.8)
actionpack (2.3.8)
activerecord (2.3.8)
activeresource (2.3.8)
activesupport (2.3.8)
authlogic (2.1.5)
builder (2.1.2)
configuration (1.1.0)
cucumber (0.8.4, 0.8.3)
cucumber-rails (0.3.2)
database_cleaner (0.5.2)
declarative_authorization (0.4.1)
diff-lcs (1.1.2)
gherkin (2.1.2, 2.0.2)
json_pure (1.4.3)
launchy (0.3.5)
mysql (2.8.1)
nokogiri (1.4.2)
paperclip (2.3.3)
pickle (0.3.0)
rack (1.2.1, 1.1.0)
rack-test (0.5.4)
rails (2.3.8)
rake (0.8.7)
rspec (1.3.0)
rspec-rails (1.3.2)
syntax (1.0.0)
term-ansicolor (1.0.5)
thoughtbot-factory_girl (1.2.2)
trollop (1.16.2)
webrat (0.7.1)
ruby 1.8.7 (2010-01-10 patchlevel 249) [i486-linux]
gem 1.3.7
running on Ubuntu
What can I do to make my cucumber steps pass!
Thanks for any help
instead of the line
flash[:notice] = "Login successful!"
redirect_to root_url
just try rendering it instead of redirecting it.
flash[:notice] = "Login successful!"
render :action => :root_url
in doing this, it seems to remember flash[:notice]
i could not get --> redirect_to root_url, :flash => { :notice => 'not found' }, :notice => Login successful!' <-- to work at all
Looks like rails 2.3.8 has changed the method in which is displays notices..
redirect_to(root_url, :notice => 'Login successful!')
might be what you're looking for.
I believe this issue will be fixed in Rails 2.3.9. It has to do with setting both a cookie and a session in the same request. See this ticket for details.
In the meantime you can use this gist as a temporary fix.
thanks to raynb who pointed me into the right direction. But unfurtunatly this solution did not work but I found this page which puts everything in cucumber.rb... which mad it running now ...
https://webrat.lighthouseapp.com/projects/10503-webrat/tickets/383-reset_session-and-webrat-dont-play-nicely-with-one-another

Resources