I need some help with clojure and oauth.
I got stuck at the last step: signing the request with the credentials.
(def credentials (oauth/credentials consumer
(:oauth_token access-token-response)
(:oauth_token_secret access-token-response)
:POST
"http://twitter.com/statuses/update.json"
{:status "posting from #clojure with #oauth"}))
(http/put "http://twitter.com/statuses/update.json"
:query-params credentials)
Thats the example from github.
Now, from the flickr API I have this test-url:
http://api.flickr.com/services/rest/?method=flickr.people.getPhotos
&api_key=82d4d4ac421a5a22et4b49a04332c3ff
&user_id=93029506%40N07&format=json&nojsoncallback=1
&auth_token=72153452760816580-cd1e8e4ea15733c3
&api_sig=b775474e44e403a79ec2a58d771e2022
I dont use twitter... I use the flickr api and want to GET the pictures of a user.
My question is now: How do I have to change the credentials that it fits the flickr url?
I am also confused about the :status but when I delete it I get an error...
The Twitter example uses the HTTP POST method, but for Flickr we want GET and the flickr api. So we do
(def credentials (oauth/credentials consumer
(:oauth_token access-token-response)
(:oauth_token_secret access-token-response)
:GET
"http://api.flickr.com/services/rest/"
query-params))
In the twitter example, what I replaced with query-params specifies what get posted. It
is a map that will be url-encoded into something like status=posting%20from%20%23clojure%20with%20%23oauth. Conversely, the request from the API you mention has the following map for the non-oauth query-params:
(def query-params {:method "flickr.people.getPhotos" :format "json" :user_id "93029506#N07" :nojsoncallback 1})
Now all we have to do is
(http/get "http://api.flickr.com/services/rest/" {:query-params (merge credentials query-params)})
Related
I am new to authentication using Oauth2, and was hoping someone could provide some guidance on how to use the oauth2 gem to correctly perform authentication so as to get a token with Microsoft Dynamics.
I have been able to authorize and get a token with Postman, but as these types of applications greatly facilitate the overall process, it can be difficult to map these things to code, especially when the concepts are new.
For the access token, I have at my disposal:
The Auth URL, which is of the form "https://login.windows.net/<CUSTOMER_IDENTIFIER_HASH>/authorize?resource=https://api.businesscentral.dynamics.com
The Access Token URL, which is of the form "https://login.windows.net/<CUSTOMER_IDENTIFIER_HASH>/oauth2/token?resource=https://api.businesscentral.dynamics.com"
The client_id
The client_secret
I've tried the various examples online, but I either get a nondescript error from oauth2 such as:
OAuth2::Error ():
Or, in other cases, something more particular:
OAuth2::Error ({"code"=>"RequestDataInvalid", "message"=>"Request data is invalid."}:
{"error": {"code": "RequestDataInvalid","message": "Request data is invalid."}}):
Does anyone have any real, working examples on how to successfully obtain a token?
Finaly cracked it.
Had to respecitvely move the resource element out of the auth and the access token urls to:
https://login.windows.net/<CUSTOMER_IDENTIFIER_HASH>/authorize
https://login.windows.net/<CUSTOMER_IDENTIFIER_HASH>/oauth2/token
At that point, i set the client as:
client = OAuth2::Client.new(
client_id,
client_secret,
site: base_url,
grant_type: "client_credentials",
resource: "https://api.businesscentral.dynamics.com",
authorize_url: auth_url,
token_url: token_url,
)
Above, the base_url is:
https://api.businesscentral.dynamics.com/v2.0/<CUSTOMER_IDENTIFIER_HASH>
Then, i call the client to get an auth_code and had to explicitly pass the resource parameter:
client.auth_code.authorize_url(:redirect_uri => 'http://localhost:8080/oauth2/callback', resource: "https://api.businesscentral.dynamics.com")
I'm not sure if the resource is necessary when getting the token, but finally, I obtain it as follows:
token = client.password.get_token(<AUTHENTICATION_LOGIN>, <AUTHENTICATION_PASS>, resource: "https://api.businesscentral.dynamics.com")
then i can use the token to perform get commands:
token.get('https://api.businesscentral.dynamics.com/v2.0/Sandbox/api/v2.0/companies(<COMPANY_ID_HASH>)/customers', :headers => { 'Accept' => 'application/json' })
I have a feeling I have to do some cleanup on the url for the final get command, but it seems to work this way.
I want to get unauthenticated access token from vimeo api in my rails app. However the post request made using HTTParty gem returns following response from API
{"error"=>"You must provide a valid authenticated access token."}
The code to send request is
header = "basic " + Base64.encode64("****07974be" + ":" + "****ygYBI7I")
token = HTTParty.post("https://api.vimeo.com/oauth/authorize/client",
:body => {:grant_type => 'client_credentials'},
:header => {'Authorization' => header}
)
json=JSON.parse(token)
I have checked that credentials are correct and also tried replacing :header with :headers, and various combinations of using string instead of symbol in the header hash. But none of them works.
However, the call to same URL, using same credentials is successful through Postman.
Edit As mentioned in a answer, we need to use headers (plural) while making the call. However, I had already tried that but problem persists. Using basic_auth, instead of sending headers do seems to work, however I can not figure out why sending headers through HTTParty is not working but similar call is working through Postman.
The :headers option is definitely plural, but since you are using basic auth, you can also use HTTParty's basic auth option. So your request would become:
username = "YOUR-USER-HERE"
password = "YOUR-PASSWORD-HERE"
token = HTTParty.post("https://api.vimeo.com/oauth/authorize/client",
body: {:grant_type => 'client_credentials'},
basic_auth: { username: username, password: password }
)
Using your creds (did you mean to post real creds?) I got
{"access_token"=>"REDACTED", "token_type"=>"bearer", "scope"=>"public", "app"=>{"name"=>"Fable", "uri"=>"/apps/REDACTED"}}
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
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.
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.