Twitter OAuth - Incorrect signature errors - what have I missed? - ruby

I have read the page on implementing OAuth that Twitter have written. I've registered my app, it will only access my account, so I skip all the request token stuff. I have, from the "Your apps" page:
consumer token
consumer token secret
access token
access token secret
I write some ruby code and test its output against Beginner’s Guide to OAuth (suggested reading in the Twitter docs). I get the same output, i.e. the signature, the base string and the Authorization headers are identical.
However, when I connect to the Twitter Rest API and try the verify credentials command the response is invariably "Incorrect signature".
I try using different code (very similar to mine) from a gist by erikeldridge on github but it doesn't work either. Instead of connecting via cURL (using the curb library) I use Net/Http - same error response is returned.
I change over to using the OAuth gem. It uses Net/Http to connect. Same error response comes back.
Verify credentials isn't the only command I've tried to use in the API, but they all give the same error, whether it's GET or POST, requires extra params or not. I've been using the Search API successfully using the curb library without problems so I don't think it's the connection method.
What might I do to fix this?
Ruby 1.9.2; cURL 7.21.2; oauth 0.4.4; curb 0.7.8; json 1.4.6; OSX 10.6.5;

Even though your application is only accessing your data, you can't simply 'skip the request token stuff'. The request token is integral to the OAuthentication process.
Summarised, the 3 main parts of the OAuth process are as follows:
Get Request Token Key and Request Token Secret
Use Request Token to authorise application to access your data. This will provided the user(you) with a PIN
Use the PIN to exchange the Request Token and Secret for an Access Token and Secret.
A more detailed OAuthentication flow can be found here.

It's fixed - I regenerated the Consumer key and secret on the Twitter site and it started working. I've no idea why the previous set didn't work - the code was solid (works all the time now) and the details were correct. Perhaps they (Twitter) could provide more detailed error messages? But I'm happy :)

Related

How to get new acess token from refres token for google api in postman

I am trying to get new access token from my refresh token for google drive api. In my google playground it works but when I want to create the same request in postman or my code it doesn't work and I always get error "Invalid grand type". I don't know to find what is problem.
google developers playground
postman headers and body
You need to understand that there is three steps to the Oauth2 dance.
step one is requesting access of the user and getting the authorization code.
HTTP GET https://accounts.google.com/o/oauth2/auth?client_id={clientid}.apps.googleusercontent.com&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=https://www.googleapis.com/auth/analytics.readonly&response_type=code
Note &response_type=code tells the server you want an authorization code returned.
step two is to exchange that code for an access token and refresh token.
POST https://accounts.google.com/o/oauth2/token
code=4/X9lG6uWd8-MMJPElWggHZRzyFKtp.QubAT_P-GEwePvB8fYmgkJzntDnaiAI&client_id={ClientId}.apps.googleusercontent.com&client_secret={ClientSecret}&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code
Note the part where it says &grant_type=authorization_code. this tells the server you are giving them an authorization code.
3 the final step is refreshing your access token.
POST https://accounts.google.com/o/oauth2/token
client_id={ClientId}.apps.googleusercontent.com&client_secret={ClientSecret}&refresh_token=1/ffYmfI0sjR54Ft9oupubLzrJhD1hZS5tWQcyAvNECCA&grant_type=refresh_token
Note &grant_type=refresh_token you are telling the server you are sending them a refresh token.
You appear to be sending a refresh token with the wrong grant type.
I have a video on how to set up postman to use google oauth2
How to set up Oauth2 in PostMan.
Google 3 Legged OAuth2 Flow
Note: Due to a recent change with Making Google OAuth interactions safer by using more secure OAuth flows redirect uri of urn:ietf:wg:oauth:2.0:oob is going to stop working soon.

Access GitHub API from Nifi

I'm trying to access info within GitHub's API from a NiFi Process. Essentially, I'm using GenerateFlowFile to set the target URL and the Authorization header for the token. I then pass it to the InvokeHTTP and every time it gets a 401 error saying it needs to be authenticated, despite providing my personal token (the one I use when programming locally and with Terminal). Any tips on how I can get this working? I can provide more detail if needed
I'm not sure which endpoint you're trying to access in the GitHub API, but it appears you are using an endpoint from GitHub Enterprise 2.22 from the error message.
The docs for authentication show you should prefix the token with token i.e:
Authorization: token OAUTH-TOKEN
In your specific case, this means you should set the Authorization header to token ${github_token}.

Error 400: invalid_scope Some requested scopes cannot be shown: [https://www.googleapis.com/auth/homegraph]

So I'm trying to use the Home Graph API by calling the API endpoint
https://homegraph.googleapis.com/v1/devices:requestSync
It is a HTTP POST request and it needs an ACCESS_TOKEN and service account key.
Getting the service account key is easily done as per Google's documentation. The issue is getting the ACCESS_TOKEN.
As per this documentation by Google, I need to get ACCESS_TOKEN created using the following scope of permissions
https://www.googleapis.com/auth/homegraph
I opened OAuth 2.0 Playground to request a developer temporary ACCESS_TOKEN for testing. I wrote all the necessary urls and in scope I wrote this-
scope is written to be authorized
Now after this, I am navigated to my Authorization URL (ie, Google's sign in page). I login with email id and password.
If credentials are correct and scope mentioned is valid then I should have been redirected to OAuth playground page with authorization code which I would have exchanged for access token and refresh token.
But, what actually happens is after I enter my credentials, I get following error and I am never redirected to Oauth Playground page-
Authorization Error
Error 400: invalid_scope
Some requested scopes cannot be shown: [https://www.googleapis.com/auth/homegraph]
Request Details
access_type=offline
o2v=2
response_type=code
redirect_uri=https://developers.google.com/oauthplayground
prompt=consent
client_id=xxxxxxxxx.apps.googleusercontent.com
scope=https://www.googleapis.com/auth/homegraph**
I searched a lot online too, but couldn't find the actual reason.
So due to this issue with scope, I am not able to get ACCESS_TOKEN.
I have followed Google's documentation and the scope was mentioned there.
This is the pic from oauth 2.0 playground settings- OAuth 2.0 configuration
The issue is that you, a user, should not be getting and sending an access token. The service account should be getting and sending an access token. This is to make sure your service is authorized to talk to the Home Graph API.
You indicated you logged into the OAuth playground with "userid and password". But service accounts don't have passwords.
If you are using one of Google's libraries, it will take care of getting the access token for you, and this is the easiest way to do so. If you are just testing and need an access token, you can use something like oauth2l to get the access token based on the service account credentials.
I had implemented the REST approach to call HomeGraph Report State as below.
We need to follow the below steps:
Create a service account for your project and safely store the json file
Using the service account JSON, get the access token from Google
Using Oauth 2.0 token as Bearer authorization, invoke Report State API
Step 1:
This is straightforward. Please follow the steps in the below link
https://developers.google.com/assistant/smarthome/develop/report-state#expandable-1
Step 2:
Refer below code to get the Access token using service account json
GoogleCredentials credentials = GoogleCredentials
.fromStream(Helper.class.getClassLoader().getResourceAsStream("smart-home-key.json"))
.createScoped("https://www.googleapis.com/auth/homegraph");
credentials.refreshIfExpired();
AccessToken token = credentials.getAccessToken();
return token.getTokenValue();
Step 3:
Invoke Report State API
curl -X POST -H "Authorization: Bearer [[Access token from Step 2]]"
-H "Content-Type: application/json"
-d #request-body.json
"https://homegraph.googleapis.com/v1/devices:reportStateAndNotification"
Reference Links :
https://developers.google.com/assistant/smarthome/develop/report-state#http-post
https://cloud.google.com/endpoints/docs/openapi/service-account-authentication
https://developers.google.com/identity/protocols/oauth2/service-account#httprest_1
https://developers.google.com/assistant/smarthome/develop/report-state#expandable-1

Ruby twitter client

I'm trying to create a ruby-based twitter client where I can post my status from command-line using ruby. I'm trying to understand the oauth right now, and it confused me a little bit. If I'm building a web application, I can provide a callback url when the request token is complete. How would I do that from the command-line? I don't want ruby to print out the authorized and copy and paste the url and click 'Allow' to get the token. I found something about out-of-band exchange or PIN. How would I do that with OAuth library in ruby, please thank you very much.
To use the callback url mechanism, you application should be a web application. It seems you are developing desktop application and if that's the case, you should follow "PIN code" flow by supplying an oauth_callback_url of "oob" (out-of-band) when you request token. Like this,
https://api.twitter.com/oauth/request_token?oauth_callback=oob
If you properly set a header of this HTTP request (setting HTTP header is the key part of OAuth and I think you already know how to do this), Twitter will give oauth_token, oauth_token_secret and oauth_verifier. Let's call this token "request_token". You need it to get "access_token" later.
Once you have request_token, you need to open web page with the below url
http://api.twitter.com/oauth/authorize?oauth_token=request_token
This will open the authorization page and let a user to decide whether the user wants to allow your application to access his or her Twitter account. If the use says okay, then Twitter gives PIN code. You need to allow a user to type the PIN code so that you can save it.
Now, it's time to get another token ("access_token") by using your comsumer_key / secret, request_token and the PIN code. You should set header with all these values correctly and do HTTP request again with this url,
https://api.twitter.com/oauth/access_token
If Twitter accepts your "access_token" request, it will give you oauth_token, oauth_token_secret, user_id and screen_name. Let's call this token "access_token". Now, you can perform any OAuth required Twitter API by using access_token and its secret (oauth_token_secret). You can save the two values in a file and keep using them whenever you need to access the user's Twitter account. The values will be always valid until the user revokes the access to your application.
I don't know Ruby but if you know how to perform HTTP/HTTPS requests (GET / POST) with custom headers in Ruby, this PIN code flow should work fine if you follow Twitter API document carefully. Good Luck!
It will ask for the PIN code until you specify the oauth_callback when getting the request token, not when forwarding the user to the authorization url
#consumer = OAuth::Consumer.new(
TWITTER_CONSUMER_KEY,
TWITTER_CONSUMER_SECRET,
{:site=>"https://api.twitter.com"})
#request_token = #consumer.get_request_token( :oauth_callback => CALLBACK_URL )
This was the result of surfing several hours of incomplete documentation.
use Twitter gem, it will make things easier for you. http://rdoc.info/gems/tweeter/2.0.0/frames

Twitter OAuth Request Token Using Grackle

I am currently trying to use the Grackle Ruby GEM to integrate with the Twitter API, but I have encountered a little snag.
I am attempting to perform a GET to twitter.com/oauth/request_token, but according to the OAuth spec I need to provide the following values:
oauth_consumer_key
oauth_signature_method
oauth_signature
oauth_timestamp
oauth_nonce
I am a little stumped, as at this point Twitter has only given me a Consumer Key and a Consumer Secret. Am I just going about this the hard way? Because I cannot figure out how to correctly populate those values. No matter what I supply Twitter keeps returning:
Failed to validate oauth signature and
token
It sounds like my problem is just a general misunderstanding on how to properly integrate with Twitter and OAuth in general, and not so much the specifics of Grackle... but perhaps too much information is best in this case :-)
First of all, you should probably be reading the latest OAuth rev, which is 1.0a. There are no differences when obtaining the request token though so you should be fine in that regard.
Apart from that, it looks like a combination of general misunderstanding of the OAuth process and the scope of Grackle:
The process of acquiring the access
token and token secret are outside the
scope of Grackle and will need to be
coded on a per-application # basis.
Grackle comes into play once you've
acquired all of the above pieces of
information (source).
So, I would first look towards a library that can get you an access token before continuing with Grackle. Moomerman's twitter_oauth looks like a good choice: http://github.com/moomerman/twitter_oauth
Hope that helps!
I encountered this same issue, and all the examples for the oauth gem online I could find were out of date. I wrote an explanation with sample code here, but the basic flow is:
Get a Request Token from Twitter and save the details
Send the user to Twitter with that token
Get the user back, use details and response from Twitter to generate an Access Token
Use the Access Token's token and secret with your Consumer token and secret to make API calls.

Resources