REST works in curl but not in Python Requests (401 error)


#1

Hi, I googled this issue, but couldn’t figure it out. I ran a REST query in Python Requests (HTTP interface), and CURL, and Python Requests does not work while CURL works.

env: Windows 10, Python 2.7.12, Requests version 2.11.1

I got access_token and I put it into the header, so my header looks like
headers = {“Content-Type”:“application/json”,
“Authorization”: “Bearer xxxxxxxxxxxxxxxxx”} #xxx corresponds to the access_token.
url = "https://https://developer-api.nest.com/structures"
resp = requests.get(url, headers=headers)

It returns 401 unauthorized access error while the same thing works in CURL. Can anybody tell the difference in these two approach? Otherwise, is there something wrong in the above code?

Thanks in advance.

(I tried to use python-firebase, but it is not working for several features such as PUT. Maybe I used it incorrectly, but hope pure REST works as well.)

UPDATE: After a long study, I found that it is working if the token is embedded in params rather than in headers. So following works:
headers = {“Content-Type”:“application/json”}
params = {‘auth’: ‘xxxxxxxxxxxxxxxxxxx’}
resp = requests.get(url, params=params, headers=headers)
assert(resp.code==200)
# Why is this working and the original one not working?


Thermostat data request succeeds in Postman but .NET HttpWebRequest returns 401
#2

I noticed in the first example you posted you called it “Authorization” when it should be called “auth” as in the second example.


#3

The Nest API always returns a 304 to point to another URL. The requests library follows redirects by default, but it does not copy the authorization headers onto the second request. Because the second request doesn’t have authorization headers, it gets a 401. By comparison, if you use the auth parameter, that is preserved across multiple requests when following.

Read a bit more about it at https://github.com/kennethreitz/requests/issues/2949 . Using the Nest API was actually the problem ran into there.

If you need a python library supporting Nest, I have been working on https://github.com/jkoelker/python-nest/pull/49


#4

Anyone know how to write the params= line in Golang?

params = {‘auth’: ‘xxxxxxxxxxxxxxxxxxx’}


#5

Thanks for the clarification! Now I understand how it works.


#6

you can just add the param to the url like this:
https://https://developer-api.nest.com/structures?auth=xxxxxxxxxxxxxxxxxxxxx


#9

I picked the above method from here: https://gist.github.com/tylerdave/409ffa08e1d47b1a1e23

I am not a network expert but I believe headers can be logged also, which is not avoidable. (Correct me if I am wrong.)

As @technicalpickles brought: authorization token redirection seems to be a still problem: https://github.com/kennethreitz/requests/issues/2949


#12

@bk7749 you can use the auth param, but the docs say it’s not recommended: https://developers.nest.com/documentation/cloud/how-to-auth#step-4---make-authenticated-requests

It is possible to send tokens as URI query-string parameters, but we don’t recommend it, because URI parameters can end up in log files that are not completely secure.


#13

Thanks, all. I see the problems. I will use the library that you suggested.