Pocket API Authorization: Forbidden - ruby-on-rails

I'm testing out RoR by building a Rails app with Pocket API, and I have to authorize the user. For HTTP requests, I'm using https://github.com/rest-client/rest-client library.
The first step, obtaining a request token works fine:
require 'rest_client'
response = RestClient.post 'https://getpocket.com/v3/oauth/request', :consumer_key => #consumer_key, :redirect_uri => #redirect_uri
#code = response.split("=")[1]
But I get a Bad Request error on the second step, which is to get an access token using the request token received on the step above:
access_token = RestClient.post 'https://getpocket.com/v3/oauth/authorize', :consumer_key => #consumer_key, :code => #code
400 Bad Request is what I get on Ruby application error screen. I have also tried the same request with cURL and POSTMan Chrome extension, and the status code I get then is: 403 Forbidden. X-Error Code I get is 158 which translates to X-Error message "User rejects code." on Pocket API docs: http://getpocket.com/developer/docs/authentication.
Since I have tried several different channels to test this request and failed each time, I'm guessing that the problem is not with parsing, but rather I might be missing an important detail or a step (maybe HTTP request headers?). Thanks for your help in advance!

Turns out that I (or we) have been missing an important detail:
Whenever testing out your request for Pocket API in POSTMan or anywhere else, we naturally skip the process of visiting the authorization URL which is in the form of:
https://getpocket.com/auth/authorize?request_token=YOUR_REQUEST_TOKEN&redirect_uri=YOUR_REDIRECT_URI
Now, even though you might have allowed your app to access your account before, on each call, Pocket API doesn't activate a request token before this URL is visited. Only then your request token becomes activated and can be used for 2nd authentication step. It works fine after doing that.
As a side note to anyone who is using Pocket API in Ruby on Rails, there is a nice wrapper gem for it: https://github.com/turadg/pocket-ruby

I can confirm that you are indeed missing HTTP headers, which will cause the Pocket server to reject the post request you're trying to send.
There are a few ways in which headers can be communicated: sometimes they are communicated through the codes/tokens associated with the server request (which here appears not to be the case). You need to use an "Authorization" header as per your doing this with OAuth with your initial request.
This should help you: notice the "Authorization:" header after the "Content-Type:" header contains the information that's returned.
For some in depth reading, go here.
I might also suggest trying the OAuth2 gem which does most of the requesting for you - it will probably simplify what you're doing quite a bit!!
Here's what it looks like on Postman.

Related

AWS and Cognito

I'm a newbie to this stuff so downloaded the samples which is all fine and I thought I could see what was going on and what I needed to do. However, got a bit stuck for no obvious reason so I wondered if anyone could maybe give me some hints.
I'm trying to engineer Cognito authentication and identity into an old Apache Struts 1 legacy web application written in Java, so all the activity needs to be server-side. Using the Cognito https://xxx.auth.xxx.amazoncognito.com/login? URL I can successfully authenticate and get an auth code back using this URL providing my client id, redirect URI and response_type=code so all good thus far.
If I then create an HttpClient (as per the sample code in Github) and call the token URL https://xxx.auth.xxx.amazoncognito.com/oauth2/token and write various parameters to the request body (grant_type=authorization_code, client_id=as previously, redirect_uri=my URI and code=auth code just returned), I get an "unauthorized_client" message returned. But the code is valid albeit for authorization, and the client_id is correct because I used it previously.
My log:
Cognito following successful signin, continuing to url http:[redacted]/passport/CognitoHandlerSignIn.do?code=62eeb0b1-a76b-489b-bd28-e42023a497bd
(this was the /login succeeding)
Callback from Cognito received
(following is the log dump of the /oauth2/token URI called to)
Cognito token signin URL is https:[redacted].amazoncognito.com/oauth2/token
HTTP request header, added Authorization=Basic M29wcGR0azdpYzF2YjloNGd0OTQzNXYxcmI6MW9mMmFsaWNzZGR2dHZ1NmFkOHRuc2s4cnJ0cXEyYm0yc3RqbG1mcmkyamhkdXBubG1wMw==
HTTP request header, added Content-Type=application/x-www-form-urlencoded
HTTP request body, added grant_type=authorization_code
HTTP request body, added
redirect_uri=https%3A%2F%2F<redacted>%2Fpassport%2FCognitoHandlerSignIn.do
HTTP request body, added code=62eeb0b1-a76b-489b-bd28-e42023a497bd
HTTP request body, added client_id=[redacted]
HTTP request is sun.net.www.protocol.https.DelegateHttpsURLConnection:https:
[redacted].auth.eu-west-1.amazoncognito.com/oauth2/token
HTTP Json result=<{"error":"unauthorized_client"}>
org.json.JSONException: JSONObject not found.
at org.json.JSONObject.get(JSONObject.java:454)
at
What's wrong with this picture? I tried also adding client_id, code as URL parameters but I just get an "invalid_client" message instead.
I also tried using the /oauth2/token URI directly from the Struts app to provide a token but it returns the id_token using # rather than ? in the parameter list so it is client-side only and hence can't be intercepted by the Struts app and so will be a pain to forward to the server, but I could write some Javascript to do it if I had to. It doesn't seem the path of least resistance, though, as it seems wrong that the pure Java server side call doesn't work so I must be doing something wrong which isn't obvious to me.

How does the implicit grant flow work?

On this page, https://github.com/doorkeeper-gem/doorkeeper/wiki/Supported-Features, it mentions support for Implicit Grants. It looks like the authorizations#create is the endpoint I want and it does return an access_token but it doesn't return the other parameters that are required.
Request
https://localhost/oauth/authorize?client_id=<client_id>&response_type=token&redirect_uri=urn:ietf:wg:oauth:2.0:oob
I get redirected to:
Redirect
https://localhost?access_token=<access_token> with the body:
{"resource_owner_id":<user_id>,"scopes":[],"expires_in_seconds":7776000,"application":{"uid":"<client_id>"},"created_at":1484857630}
What I need per the spec, is a redirect with query parameters:
https://localhost#access_token=<access_token>&token_type=bearer&expires_in=<seconds>&scope=<scope>
Is the use of the testing redirect value of "redirect_uri=urn:ietf:wg:oauth:2.0:oob" changing the response?
Also notice the ? instead of the # just before the response query parameters. I'm not sure what the spec says on that but Amazon OAuth2 clients require the # sign.
How do I get the token_type=bearer be included?
Thanks.
I was able to get my service working by looking at the code. So the answers to my questions above are:
urn:ietf:wg:oauth:2.0: is called the native URI. There is branching in the code which alters the response when it's set to the native URI. Using ngrok to create an externally callable endpoint on my local machine, I used a true redirect_uri value and Doorkeeper responded with the correct parameters in the response (including the token_type=bearer and # sign).
Note: It worked from my Amazon Alexa skill only after modifying the Doorkeeper code to allow redirect URLs that contain query parameters. Amazon's redirect URLs are in the format https://pitangui.amazon.com/spa/skill/account-linking-status.html?vendorId=<vendorId> which is currently not supported by Doorkeeper and an error is thrown about an Invalid Redirect URI.

Sending authorize request to twitter API for followers ids

I want to send authorize request to twitter API in order to get followers ids, i got access token and access token secret by creating a new application as shown here. I have no idea how to send authorize request in pharo smalltalk.
I want to get followers ids by performing this in pharo smalltalk .
I wanna know if there is any documentation or packages that can help me with this.
Here is the code i tried to work with.
|client|
client:= ZnClient new.
client https;
host: 'www.api.twitter.com/1.1/followers/ids.json';
queryAt: 'q' put: 'cursor=-1&screen_name=my name'.
client request headers at: 'Authorization' put:' OAuth oauth_consumer_key="Hp6FpBU7Bbqv89RqrHJzHw", oauth_nonce="9677be3a12e128702b06348677319e75", oauth_signature="GUQR%2FI%2Bd0XhQLJP5B0IHtDfiiLE%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1387729271", oauth_token=" my acess token", oauth_version="1.0" '.
client get.
Welcome to Pharo community, Irfan.
You should take a look at Zinc framework. Here is a very nice documentation, you should be able to solve your problem after reading it.
Also as far as I know there is work in progress on the OAuth protocol, you can take a look here: https://github.com/svenvc/docs/blob/master/zinc/zinc-sso-paper.md. You definitely want to take a look at it because there are also 2 demos where you can interact with twitter

Make a request with an "consumer token" with oauth2

I'm using intridea/oauth2 for oauth2 functionality. Everything is working fine with authentication and making requests with an access token.
But what i can not find out is how to make a request without an access token. I thought it would simply work with
client = OAuth2::Client.new(key, secret, :site => site)
client.request(:post, "/api/users", {params: {param1: "val1"}})
but that does not seem to work. It is not setting any oauth header in the request.
How do i make a request like that?
Leave out oAuth completely then. Use simple Net::HTTP requests or use a library like REST Client for example.
It seems like the library isn't capable of something like that. So i now have two ways of authentication. You can find some information on this page: http://railscasts.com/episodes/352-securing-an-api?view=asciicast

HTTP Get Request

I've been trying to get Rails to play with the new Facebook Graph API. After I get the authorization "code", I need to send another request which returns the access token in JSON form.
It seems to work fine, however I want to fetch the access token JSON without redirecting the user. I'm attempting to use Net::HTTP.get, but I'm not sure how to use it to get a request body, or even if it's the right thing to use to begin with.
Can anyone give an example of performing an HTTP GET?
I've figured out how to do this, the problem was mainly with the fact that I needed an HTTPS connection.
Adapted from http://snippets.dzone.com/posts/show/788:
path = '/oauth/access_token?...'
http = Net::HTTP.new('graph.facebook.com', 443)
http.use_ssl = true
res = http.get(path, nil)
#access_token = res.body
Anyone specifically trying to use the Graph API, note that the value stored in #access_token is in the form of a params string, e.g. "access_token=xxxx&expires=1234".
I got around needing to parse this by just redirecting to another page and using that as the URL params, but there's probably a better way to do this.
SOA#1
However please note that it means that server have to be log onto facebook - while if browser is redirecting it is user who have to be log into server. Hence did your server set the permission?
You can pretend that you are the user. Bad Horrible idea (you have to store passwords in cleartext on you server).
You can use OAuth. Hence you should use OAuth gem instead of Net::HTTP. You will not avoid the redirection - it is part of authorisation process and user must say that he allows to access data (imagine what would be if anyone could access anyone data on facebook). Turorial on writing OAuth clients in rails.

Resources