Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple requests over a Rauth OAuth 1.0 session

We're using Rauth to connect to various OAuth 1 APIs. It works fine for a single request, but trying to do 2 or more requests against the given session results in 401 not authorized errors from the APIs.

Twitter API example:

import requests
from rauth import OAuth1Service
from rauth import OAuth1Session

consumer_key = {the consumer key}
consumer_secret = {the consumer secret}
access_token = {the access token}
access_token_secret = {the access token secret}

oauth_service = OAuth1Service(consumer_key = consumer_key, 
                            consumer_secret = consumer_secret)
oauth_session = oauth_service.get_session(token = (access_token, access_secret))

url = 'https://api.twitter.com/1.1/statuses/home_timeline.json'
params = {'include_rts': 'true'}
r = oauth_session.get(url, params=params) # THIS WORKS
r = oauth_session.get(url, params=params) # THIS RETURNS 401 ERROR

This happens on both Twitter and LinkedIn APIs. How do we execute multiple requests against a single OAuth1Session object?

VERSIONS:
rauth==0.5.4
requests==1.1.0


UPDATE:

Strangely, if the params argument is not included then multiple requests can be made- but once params are included, even if it is an empty dict, we get 401s.

Example 1:

r = oauth_session.get(url) # THIS WORKS
r = oauth_session.get(url) # THIS WORKS

Example 2:

r = oauth_session.get(url, params={}) # THIS WORKS
r = oauth_session.get(url, params={}) # THIS RETURNS 401 ERROR
like image 215
Yarin Avatar asked Oct 22 '22 11:10

Yarin


1 Answers

Carrying over from the comments, using session.get(..., header_auth=True) should do the trick. It's hard to say exactly why it doesn't work without this, but for the record, header-based authentication is preferred by the spec and given Twitter's position, I wouldn't be surprised if they also prefer it as a provider.

A quick search reveals dozens upon dozens of reports of their API failing where it ostensibly should work and one remedy is to prefer header authentication. From what I can tell, rauth is signing appropriately, so perhaps this is something to do with the way the provider is showing preference and handling non-header authenticated requests.

Update

It looks like either rauth or Requests was not properly handling params. It's odd because the signature base string and oauth_signature seemed to be correct, in that they were appropriately different on each respective request and the data they operated on seemed to checkout. So it seems like it should have validated the request.

At any rate, to correct this, we need to deepcopy elements of the request parameters that are mutable types, e.g. dictionaries. I've got a patch that should correct this, so you should be able to use this without header_auth. However, header authentication is the preferred method so I would still recommend it.

like image 72
maxcountryman Avatar answered Oct 24 '22 09:10

maxcountryman