Search code examples
pythonhttppython-requestsbattlenet-api

what's the difference between requests.post and this straight curl?


Using python 3.6.2 with requests library.

I'm trying to authenticate with oauth2 on battle.net APIs, and on the second request (the one for token retrieval) I'm getting a 400 error with no useful explanation ("internal server error"). Someone on the battle.net forum suggested to try to do the same POST with a curl, and it works. (here's my forum post: https://us.battle.net/forums/en/bnet/topic/20762236765)

I checked many times for some stupid difference between the two (maybe a typo), but there aren't (I also written back the request from the curl by copypasting, obtaining the same error). So I suppose there should be some actual difference in behaviour between the two.

Here's the python code:

data = {
         'code': code,
         'redirect_uri': 'https%3A%2F%2Flocalhost%2Foauth2callback',
         'grant_type': 'authorization_code',
         'client_id': CLIENT_ID,
         'client_secret': CLIENT_SECRET,
         'scope': 'sc2.profile'
    }
resp = requests.post('https://eu.battle.net/oauth/token', data=data)

And here's the curl:

curl -X POST -s "https://eu.battle.net/oauth/token" \
    -d client_id='<same as above>' \
    -d client_secret='<same as above>'  \
    -d grant_type='authorization_code' \
    -d redirect_uri='https%3A%2F%2Flocalhost%2Foauth2callback' \
    -d scope='sc2.profile'  \
    -d code='<same as above>'

As I said, I guess there should be something different, but I'm no expert of http. Something in the headers maybe? How can I set requests to have the same behaviour?


Solution

  • You don't need to manually encode the redirect_uri; requests will do that for you.

    data = {
         'code': code,
         'redirect_uri': 'https://localhost/oauth2callback',
         'grant_type': 'authorization_code',
         'client_id': CLIENT_ID,
         'client_secret': CLIENT_SECRET,
         'scope': 'sc2.profile'
    }
    resp = requests.post('https://eu.battle.net/oauth/token', data=data)
    

    The equivalent curl call would use --data-urlencode instead of -d/--data.

    curl -X POST -s "https://eu.battle.net/oauth/token" \
        -d client_id='<same as above>' \
        -d client_secret='<same as above>'  \
        -d grant_type='authorization_code' \
        --data-urlencode redirect_uri='https://localhost/Foauth2callback' \
        -d scope='sc2.profile'  \
        -d code='<same as above>'
    

    To debug problems like this, you can post to https://httpbin.org/post; the response will show you exactly what data was sent in the POST request.