OAuth call for a request token yields a 404 error - ruby-on-rails

I am having an incredibly difficult time getting the OAuth gem working correctly for the Flickr API. I'm trying to generate a request token using this code:
user_oauth = OAuth::Consumer.new(consumer_key, consumer_secret, :site => "https://secure.flickr.com/services")
request_token = user_oauth.get_request_token(:oauth_callback => callback_url)
Whenever I run this code it throws an exception "OAuth::Unauthorized (404 Not Found)" on the call to .get_request_token.
I got my end point from: http://www.flickr.com/services/api/misc.overview.html
My OAuth gem is using the default request_token path, which should work with Flickr according to: http://www.flickr.com/services/api/auth.oauth.html#request_token I also tried using the endpoint that this link uses (http://www.flickr.com/services)
When I call .request_token_url on my OAuth::Consumer object, it returns "https://secure.flickr.com/services/oauth/request_token", which I can access in my browser. Thinking that the flickr API might only work with GET requests, I changed the OAuth method to GET and it still didn't work.
I've used this exact same code on different APIs before and it worked, so I'm not really sure what to do at this point. Any help would be appreciated!

I had the same problem. Request_token_url method returns right url, but I watch on true requested url by wireshark and there was www.flickr.com/oauth/request_token.. So it needs to move /services path from :site option into paths options.
This code works for me, now:
consumer = OAuth::Consumer.new(key, secret,
:site => "http://www.flickr.com",
:request_token_path => '/services/oauth/request_token',
:authorize_path => '/services/oauth/authorize',
:access_token_path => '/services/oauth/access_token')
request_token = consumer.get_request_token

I was having the same issue, but my callback url was "oob" which they say to use if you don't have access to a browser. Anyway I took the quotes off the oob and it works now.

Related

Undefined method `OAuth' when making HTTP request to Twitter api

I'm getting the following OAuth error when trying to make a request to the Twitter streaming api:
"#NoMethodError: undefined method `OAuth' for #TwitterMoment:0x007fa081d821f0"
def query
authorisation_header = OAuth oauth_consumer_key=ENV["oauth_consumer_key"], oauth_nonce=ENV["oauth_nonce"], oauth_signature=ENV["oauth_signature"], oauth_signature_method=ENV["oauth_signature_method"], oauth_timestamp=ENV["oauth_timestamp"], oauth_token=ENV["oauth_token"], oauth_version=ENV["oauth_version"]
response = HTTParty.get("https://stream.twitter.com/1.1/statuses/filter.json?locations=-#{#bounds}", headers: {"Authorization" => authorisation_header})
end
OAuth is included in my gemfile.
Any ideas would be very much appreciated! This is my first Stack Overflow question :)
You're using OAuth here as a function/method, but that method doesn't exist. There's no def OAuth(...) anywhere in the oauth gem, so it explodes and gives you that NoMethodError.
Judging from the Header example at the bottom of this question, I think you've confused the header string for Ruby code.
Instead, you either need to make the string yourself (a bit annoying to do safely), or use the OAuth gem's methods (API) to do so.
Here's an example from the OAuth github repo:
consumer = OAuth::Consumer.new(
options[:consumer_key],
options[:consumer_secret],
:site => "http://query.yahooapis.com"
)
access_token = OAuth::AccessToken.new(consumer)
response = access_token.request(
:get,
"/v1/yql?q=#{OAuth::Helper.escape(query)}&format=json"
)
rsp = JSON.parse(response.body)
pp rsp
This example may work for you (I'm not able to test it locally here, sorry):
def query
consumer = OAuth::Consumer.new(
ENV["oauth_consumer_key"],
ENV["oauth_consumer_token"],
site: "https://stream.twitter.com"
)
access_token = OAuth::AccessToken.new(consumer)
response = access_token.request(
:get,
"/1.1/statuses/filter.json?locations=-#{OAuth::Helper.escape(#bounds)}"
)
response = JSON.parse(response.body)
pp response # Just a bit of debug printing for the moment; remove this later.
response
end
An addendum:
Usually I might have directed you to use an existing Twitter client gem, such as https://github.com/sferik/twitter, but in this case it looks like they haven't implemented the Moments API yet.

Access Google Contacts API on Ruby

I'm struggling to access the Google Contacts API.
First I tried the google-api-ruby-client gem but it turned out that it does not support the Contacts API.
Next shot was the google_contacts_api gem but I struggle to get a oauth_access_token_for_user with the oAuth2 gem. When following the oAuth2 instructions I don't know what to put in authorization_code_value and Basic some_password.
I tried the following:
require 'oauth2'
client = OAuth2::Client.new(ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET'], :site => 'http://localhost:9292')
=> #<OAuth2::Client:0x007fcf88938758 #id="blabla.apps.googleusercontent.com", #secret="blabla", #site="http://localhost:9292", #options={:authorize_url=>"/oauth/authorize", :token_url=>"/oauth/token", :token_method=>:post, :connection_opts=>{}, :connection_build=>nil, :max_redirects=>5, :raise_errors=>true}>
client.auth_code.authorize_url(:redirect_uri => 'http://localhost:9292')
=> "http://localhost:9292/oauth/authorize?client_id=blabla.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A9292&response_type=code"
token = client.auth_code.get_token('authorization_code_value', :redirect_uri => 'http://localhost:9292', :headers => {'Authorization' => 'Basic some_password'})
=> Faraday::ConnectionFailed: Connection refused - connect(2) for "localhost" port 9292
I would appreciate if someone could give me detailed step by step instructions how to access the API.
Make sure your app is set up properly and that you've enabled the Contacts API in the Google Developers Console. Then try this:
CLIENT_ID = '?????.apps.googleusercontent.com'
CLIENT_SECRET = 'your_secret'
REDIRECT_URI = 'your_redirect_uri'
client = OAuth2::Client.new(CLIENT_ID, CLIENT_SECRET,
site: 'https://accounts.google.com',
token_url: '/o/oauth2/token',
authorize_url: '/o/oauth2/auth')
url = client.auth_code.authorize_url(scope: "https://www.google.com/m8/feeds",
redirect_uri: REDIRECT_URI)
Visit url in your browser and log in to Google. The url you are redirected to afterwards will contain the token in the parameter code. It will look like this (this next line is not code you run):
actual_redirect_url = "#{REDIRECT_URI}?code=#{code}"
Parse the code from the redirect url, then
token = client.auth_code.get_token(code, :redirect_uri => REDIRECT_URI)
Edit
Someone asked in the comments how to pass the token to the google_contacts_api library. (I wrote the library, so I should know!)
token is an OAuth2::AccessToken object in this example. All you have to do is pass it to the constructor:
user = GoogleContactsApi::User.new(token)
To be extra clear, the constructor accepts the token object, not a string.
It looks like you're authenticating against localhost (should only be referring to localhost in the context of redirecting after authentication). You should be authenticating against Google's OAuth server somewhere in there.
See: https://github.com/google/google-api-ruby-client/blob/master/lib/google/api_client.rb#L165

Rails: OAuth2 gem returns 400 error when attempting to connect to facebook

I'm attempting to add Facebook connect to our web app, and I'm running into a problem with. Everything works fine locally (I can authenticate through Facebook), but when I push the code to our dev server (which lives in the wild), every time I try to authenticate it returns the following error code:
OAuth2::HTTPError: Received HTTP 400 during request
That's really the only explanation I'm getting. Again, this works on my local machine, and the gems and such match between boxes, so I'm a bit confused. Here's the code I'm executing.
def facebook_connect
#Set the scope we want to pull from Facebook, along with the callback URL
options = {
:redirect_uri => facebook_callback_url,
:scope => "email,publish_stream"
}
#Go out and fetch the url
client = OAuth2::Client.new(FACEBOOK_API_KEY, FACEBOOK_SECRET, {:site => FACEBOOK_API_URL, :access_token_method => :post})
#Redirect to the callback for processing
redirect_to client.web_server.authorize_url(options)
end
def facebook_callback
#Client URL
client = OAuth2::Client.new(FACEBOOK_API_KEY, FACEBOOK_SECRET, {:site => FACEBOOK_API_URL, :access_token_method => :post})
#Parse out the access token
access_token = client.web_server.get_access_token(params[:code], :redirect_uri => facebook_callback_url)
#Get the user
fb_user = JSON.parse(access_token.get('/me'))
#Do some authentication database stuff
end
def facebook_callback_url
uri = URI.parse(request.url)
uri.path = '/users/facebook_callback'
uri.query = nil
uri.to_s
end
I searched Google, but the solutions that show up aren't working. Also, if anyone knows how to parse and display OAuth2 errors, I would appreciate that, as well. Thanks
Assuming that Facebook OATH knows of your server's IP address(they are very strict about it), I would recommend that you use use 'rescue' to catch that exception, get the backtrace and then find where it is being raised and place a bunch of debug statements to check the state of both request and the response, as well as access tokens.
Or you can configure remote debugging with Rubymine or NetBeans which is not an easy task :)
The issue actually ended up being a problem with the "Faraday" gem. Our dev server wasn't set up to handle SSL, which was returning an error code. We patched it using the following answer:
OmniAuth & Facebook: certificate verify failed

Getting a 401 oauth_signature error when trying to get an request token from Evernote using OAuth

I am trying to get an Evernote request token using the OAuth gem with Ruby on Rails:
customer = OAuth::Consumer.new("consumer_key_here", "consumer_secret_here",{ :site=>"http://sandbox.evernote.com/",:request_token_path => "/oauth",:oauth_signature_method => "PLAINTEXT" })
#request_token = customer.get_request_token
But I'm getting this error
OAuth::Unauthorized in PagesController#home
401 oauth_signature
What could be causing this?
Change site url to use https - I had the same issue.
Evernote's sample code now contains a Ruby OAuth example that uses the OAuth gem. You can download the sample code from http://www.evernote.com/about/developer/api/.
In this case, you need to pass the oauth_callback parameter when getting a request token, because the Evernote OAuth provider implements OAuth 1.0a.
consumer = OAuth::Consumer.new(consumerKey, consumerSecret, {
:site => "https://sandbox.evernote.com/",
:request_token_path => "/oauth",
:access_token_path => "/oauth",
:authorize_path => "/OAuth.action"})
requestToken = consumer.get_request_token(
:oauth_callback => "http://www.me.com/callback")
Also, there's no need to set the signature method to PLAINTEXT; Evernote's provider supports HMAC-SHA1, which is what the OAuth gem uses by default.
You need to put your OAuth consumer key and consumer secret in the new method where it currently says "consumer_key_here" and "consumer_secret_here".
If you do have values there for your real code, check and make sure they are correct-- it sounds silly, but I had this same problem yesterday with OAuth and it turns out I was using the wrong variables.

Rails app using Oauth to post to Twitter, getting "not authorized" when running in production server. OK in localhost

I'm trying to use Twitter's Oauth Single Token for posting from a rails app to my twitter feed (single user use-case is perfect for my app). This Is what I'm talking about.
Here's the relevant part of my code:
twitter_consumer_key = 'AAAAAA...'
twitter_consumer_secret = 'BBBBBB///'
oauth_token = 'CCCCC....'
oauth_token_secret = 'DDD.....'
consumer = OAuth::Consumer.new(twitter_consumer_key, twitter_consumer_secret, :site => "http://api.twitter.com", :scheme => :header)
access_token = OAuth::AccessToken.from_hash(consumer, :oauth_token => oauth_token, :oauth_token_secret => oauth_token_secret)
response = access_token.post("http://api.twitter.com/1/statuses/update.json", {:status => "Coffee's ready at 191 Peachtree!! "+Time.now.to_i.to_s})
logger.info response.inspect
When I run this in my local machine, everything goes well and the post is created on my feed. When I run it on my production server (centos5.5, Apache 2, Passenger, Rails 3.0.4) I get "HTTPUnauthorized".
Any ideas on how to troubleshoot this?
Thanks in advance.
Try with filling Callback URL in settings of your application on dev.twitter.com.
Should be something like that:
Callback URL http://yousite.com/auth/twitter/callback
Per abraham's comment, I'm adding the solution as an answer instead of a comment:
My server's timezone was incorrectly set so I was getting the following error in the response body:
{"request":"\/1\/statuses\/update.json","error":"Timestamp out of bounds"}
I set the time and timezone correctly and now it's working fine.
:)

Resources