Rails: OAuth::Unauthorized 401 Authorization Required using OmniAuth-Twitter - ruby-on-rails-3

I have implemented several different strategies found in StackOverFlow, but so far, none seem to affect the error being thrown:
OAuth::Unauthorized
401 Authorization Required
I am following Ryan Bates' RC #241 and get to the point where I click "Sign-in with Twitter" and I get the error. I went ahead and added the response route to the routes.rb file as listed here:
routes.rb:
match 'auth/twitter/callback', to: 'user#update'
thinking that the error might be caused from the callback function. Same error. A look at my dev.log shows this:
Started GET "/auth/twitter" for 127.0.0.1 at 2014-09-16 18:52:08 -0600
(twitter) Request phase initiated.
OAuth::Unauthorized (401 Authorization Required):
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 (1.0.1) lib/omniauth/strategies/twitter.rb:60:in `request_phase'
omniauth (1.2.2) lib/omniauth/strategy.rb:215:in `request_call'
omniauth (1.2.2) lib/omniauth/strategy.rb:183:in `call!'
omniauth (1.2.2) lib/omniauth/strategy.rb:164:in `call'
omniauth (1.2.2) lib/omniauth/builder.rb:59:in `call'
...
script/rails:6:in `require'
script/rails:6:in `<top (required)>'
-e:1:in `load'
-e:1:in `<main>'
So I know the issue is with the authentication with Twitter going out. Must be the KEY and SECRET, right?
Now, I have put the KEY and SECRET in as ENV[] variables, as direct strings to the environment/development.rb file, taken out the "ENV[]" variables, etc., as per suggestions found all over Stack.
My KEY and SECRET now reside in a custom configuration as discussed here...
config/initializers/social_media.rb:
TWITTER_CONFIG = YAML.load_file("#{::Rails.root}/config/twitter.yml")[::Rails.env]
The config/initializers/omniauth.rb file:
OmniAuth.config.logger = Rails.logger
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter, TWITTER_CONFIG['app_id'], TWITTER_CONFIG['secret']
end
Any ideas on the ActionController: Exception caught OAuth::Unauthorized - 401 Authorization Required? This is probably a Noob error, but my Google-Fu is just Google-F'ed right now...

After a night of tearing my hair out, I took at look at the callback URL on Twitter developer console.
Save yourselves some trouble and don't forget to set this. It's not mentioned directly in the RailsCast, although Ryan does briefly pass over it.
When you set the callback URL, don't just put //localhost:3000 it won't work. Instead use:
http://127.0.0.1:3000/

I had this same issue when working on a Rails 6 application with omniauth-twitter and devise gems
I had added the API Key and the API Secret Key to my Rails 6 application, but when I try to test the Twitter Authentication, I run into the error below:
OAuth::Unauthorized 401 Authorization Required
Here's how I solved it:
I added the following Callback URLs to my Twitter developer account:
http://localhost:3000/auth/twitter
http://localhost:3000/auth/twitter/callback
http://localhost:3000/users/auth/twitter
http://localhost:3000/users/auth/twitter/callback
Note: Replace localhost:3000 with your actual host. Also, the routes used for the callback URLs should match the ones that were set up in your application.
Resources: How to Sign in with Twitter using Devise, Omniauth, and Ruby on Rails
That's all.
I hope this helps

Related

omniauth google-oauth2 with devise - invalid_credentials and "Csrf detected"

Dear Fine People of SO:
I am developing a Ruby app on Rails 3.2.12 (and I am still new to it).
I am trying to get Devise working with Omniauth... the first strategy I am trying is Google_oauth2.
I have it working to the point where Google has redirected back into my localhost:3000 instance after selecting the credentials I want to use in Google.
Upon this redirection back into localhost, I see a flash notice:
Could not authenticate you from GoogleOauth2 because "Csrf detected".
The server logs contain this:
Started GET "/users/auth/google_oauth2" for 127.0.0.1 at 2013-03-21 08:57:01 -0400
(google_oauth2) Callback phase initiated.
(google_oauth2) Callback phase initiated.
(google_oauth2) Authentication failure! invalid_credentials: OmniAuth::Strategie
s::OAuth2::CallbackError, OmniAuth::Strategies::OAuth2::CallbackError
Started GET "/users/auth/google_oauth2/callback?state=7849a3762d07e7f89e69b4aa46
7efc7b7b2c21655193396b&code=4/v-dSBwAvQUUZL87iNV_yk_Z8s_x0.cnqsdbDX4gUYaDn_6y0ZQ
NgQ9hAaewI" for 127.0.0.1 at 2013-03-21 08:57:40 -0400
Processing by OmniauthCallbacksController#failure as HTML
Parameters: {"state"=>"7849a3762d07e7f89e69b4aa467efc7b7b2c21655193396b", "cod
e"=>"4/v-dSBwAvQUUZL87iNV_yk_Z8s_x0.cnqsdbDX4gUYaDn_6y0ZQNgQ9hAaewI"}
Redirected to http://localhost:3000/users/sign_in
Completed 302 Found in 0ms (ActiveRecord: 0.0ms)
I noticed that I get exactly the same result if I simply put the callback URL into the browser directly, without any parameters supplied.
http://localhost:3000/users/auth/google_oauth2/callback
What can I try? What other info can I provide?
Answering my own post.... I'm past this. I'm not entirely sure why, but I have some clues that might be worth passing on.
There are a bunch of other similar issues reported related to the omniauth-facebook strategy. They did not seem to apply to google, so I didn't look too deep. Then I tried to configure the FB strategy, and got the same problem. The FB solution was to revert the omniauth-facebook gem back to 1.4.0.
gem 'omniauth-facebook', '1.4.0'
This also automatically reverted the omniauth-oauth2 gem (I've not wrapped my head around the gem thing yet). When I tried the google link again, it did not throw the same Csrf detected message... Hmmm... reverting the FB gem fixed google ---- Need a disclaimer here, other things might have been the problem here, but I think I have it correct.
There is another problem worth mentioning. The log i provided above showed 2 repeated log messages....
(google_oauth2) Callback phase initiated.
(google_oauth2) Callback phase initiated.
This reveals another (maybe related) problem. It means that the callback was executed twice. Once I got past the CSRF issue, i started getting the invalid_credentials problem all by itself. The reason for the error is the duplicate callback call. Apparently, Oauth2 only allows a single use of the credential. The second use is invalid.
I used railscast #235 as my guide:
http://railscasts.com/episodes/235-devise-and-omniauth-revised?autoplay=true
It had me add "provider" calls in the omniauth.rb initializer. and config.omniauth calls in the devise.rb initializer. I guess these somehow result in duplicate callbacks?!?!?
Removing the entry from omniauth.rb got me past that one.
So there you have it. My second SO question, and my second question where I'm the only responder. Not sure if its because they were dumb or hard... I hope the latter.
I had the same problem. In my case I have initialized google-oauth credentials in both devise.rb and also in omniauth.rb; because of this the callback was happening twice. After removing google-oauth credentials from devise.rb, this CSRF token problem got solved.
Just stumbled onto this issue, but your fix didn't work for me. I am using the following gem versions;
oauth2 (0.8.1)
omniauth (1.1.4)
omniauth-oauth2 (1.1.1)
omniauth-facebook (1.4.1)
omniauth-google-oauth2 (0.2.1)
What did fix my problem was adjusting my omniauth.rb initialiser to the following;
OmniAuth.config.full_host = "http://localhost:3000"
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, KEY, SECRET,
provider :google_oauth2, KEY, SECRET, :scope => "userinfo.email,userinfo.profile"
end
The key part was to add the 'scope' parameter for google_oauth2, without which I was getting auth failures.
I based my install of this blog: http://sreeharikmarar.blogspot.com.au/2013/01/omniauth-devise-authentication-using.html
A related post: OmniAuth using google oauth 2 strategy scope failure

where in the Rails 3 stack are cookie_store-based sessions verified?

Assuming one is using :cookie_store, rails session are stored client-side in a signed (but unencrypted) string in a cookie.
Relevant documentation implies that this signature is verified on the server for each request, but I haven't been able to track down where this actually happens. Where in the Rails stack is the session hash verified? Is there something I need to turn on or check?
This is distinct from protect_from_forgery, which as I understand it serves to protect non-GET requests (e.g. form submissions), correct?
It's part of the actionpack gem. File action_dispatch/middleware/cookies.rb, line 291

No route found for omniauth developer strategy

I've just updated Omniauth from 0.2.6 to 1.1.1 in order to use the developer strategy. I've made my login link point to /auth/developer if the environment is development and /auth/facebook if production.
The Facebook strategy still works. When using the developer strategy, the link goes to the built-in Omniauth sign in page but returns a 404 when clicking sign in. This model does not use Devise.
Routes file
get "/auth/:provider/callback" => "sessions#create"
.
.
.
get '*a', :to => 'errors#routing'
Omniauth initializer
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, [etc.]
provider :developer if Rails.env.development?
end
Log
Started GET "/auth/developer" for 127.0.0.1 at 2012-12-19 16:23:04 +0200
Started POST "/auth/developer/callback" for 127.0.0.1 at 2012-12-19 16:23:10 +0200
ActionController::RoutingError (No route matches "/auth/developer/callback")
Ran into this today in a new rails 4 application, I'm currently using this route as a workaround:
match '/auth/:provider/callback', to: "sessions#create", via: [:get, :post]

Sinatra Warden with existing Ruby on Rails application that uses Devise

I am trying to split my current Ruby on Rails 3 web-application and it's web-services (API). My web-application is running on Heroku and implements API as a namespaced route within my application. For example /events returns a HTML page and /api/v1/events returns a JSON data.
According to some best practices, I want to split those into two different applications. I have chosen Sinatra to implement the API application. It works now for simple requests where authentication is not required.
My Ruby on Rails 3 application is using Devise to authenticate users. There's also ability to login with Facebook account. Now what I want to achieve, is HTTP Basic Authentication of users (including registration) through my Sinatra-based API by using Warden.
What is the best way to do that? Or maybe I can use something different then Warden?
Keep in mind that I am not very familiar with Rack :)
I was able to get it working. There were a few main aspects:
Get Devise working with Rails (Devise is a Rails app, won't work
without it)
Setup the mapping (route) on Rack level to support both Rails and Sinatra
Share the sessions between Rails and Sinatra
Setup Warden and make it available to Sinatra
Here is most relevant part of code from /config.ru:
#
# ...
# Rest with Rails
map "/" do
run MyApp::Application
end
# Anything urls starting with /slim will go to Sinatra
map "/slim" do
# make sure :key and :secret be in-sync with initializers/secret_store.rb initializers/secret_token.rb
use Rack::Session::Cookie, :key => '<< see, initializers/secret_store.rb >>', :secret => '<< copy from initializers/secret_token.rb >>'
# Point Warden to the Sinatra App
use Warden::Manager do |manager|
manager.failure_app = AppMain
manager.default_scope = Devise.default_scope
end
# Borrowed from https://gist.github.com/217362
Warden::Manager.before_failure do |env, opts|
env['REQUEST_METHOD'] = "POST"
end
run AppMain
end
See, http://labnote.beedesk.com/sinatra-warden-rails-devise for a complete solution.

RSpec with Capybara - test signing in with OpenID

I am creating request specs following the Railscast at http://railscasts.com/episodes/257-request-specs-and-capybara
In my application, users sign in using their Google OpenID accounts with OmniAuth (http://railscasts.com/episodes/241-simple-omniauth). How can I test this with RSpec and Capybara? When my application redirects to the Google sign in page, I get the following error:
ActionController::RoutingError:
No route matches "/accounts/o8/ud"
It seems that it doesn't allow redirecting away from the application, so how should I test this?
I have no experience with Capybara and can therefore not comment on your question, however, I have saved a bookmark for later usage that may be useful to you: http://blog.zerosum.org/2011/03/19/easy-rails-outh-integration-testing.html