Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

Refresh Tokens using Python requests Edited

I will go straight to the question. How do I refresh the bit bucket token OAuth 2.0 using python requests.

According to https://developer.atlassian.com/cloud/bitbucket/oauth-2/ this is what they recommend.

$ curl -X POST -u "client_id:secret" \
  https://bitbucket.org/site/oauth2/access_token \
  -d grant_type=refresh_token -d refresh_token={refresh_toke
n}
 Only to get this {"error_description": "Invalid refresh_token", "error": "invalid_request"}

 Mainly I want to do this in python and here is my approach

import requests
auth = ("I put real client_id here", "and-i-put-secret-here")

params={"grant_type":"refresh_token", "refresh_token":"The-token-i-want-to-refresh"}

h={"Content-type": "application/json"}

ret = requests.post(refurl, auth=auth, params=params, headers=h)
# the response is 400 and when i do


ret.content

'{"error_description": "Unsupported grant type: None", "error": "invalid_grant"}'


The same error as the curl they recommended.

The question is how do I refresh the token.

1 answer

1 accepted

0 votes
Answer accepted

Hello @latest-release,

Thanks for reaching out.

Three things I can see:

  • refresh_token parameter is not really the token you want to refresh, it's the token you're refreshing an access token with. So basically when you set up OAuth 2.0 you got two tokens: access token (short-lived) and refresh token (long-lived) which you need to use here to get the new access token (and potentially new refresh token).
  • there should be no Content-Type: application/json header, as this request should have no JSON payload.
  • instead of params you should be passing parameters in data (which is what -d option does in curl) to submit them as a form.

This works fine:

import requests
auth = ("<consumer_id>", "<consumer_secret>")

params = {
"grant_type":"refresh_token",
"refresh_token":"<your_refresh_token_here>"
}

url = "https://bitbucket.org/site/oauth2/access_token"

ret = requests.post(url, auth=auth, data=params)

Hope this helps.

Cheers,
Daniil

Thanks you @Daniil Penkin  I will try out your solution and post a happy reply.

This makes no sense. What's the point of refresh tokens if you have stored the client ID/key and secret, and can just get a new access token that way?

Your sarcastically replying to a solution that was already solved that's what makes no sense at all. You think each application has the same design storing tokens, What if tokens expire and yes they do expire, what would you do? Purge the whole app? and each token issuer has a way of refreshing or renewing.

There's literally no sarcasm in what I'm saying at all. I must be missing something - the idea of a refresh token is that it's a bit safer to store it on a machine than the original credentials used to obtain the access token. So if you need the original credentials to refresh an access token, you could avoid the refresh token part of things and literally just get a new access token, no?

In other words, if I have to store the client ID and client secret somewhere in order to use a refresh token, why bother with refresh tokens?

I expected to be able to call an endpoint with nothing more than the refresh token, and get a new access token and refresh token back.

Hi @nbarnwell,

You can't get new access token with just client ID and key. You also need some user "input" unless you're after Client Credentials Grant which would create a token not for the end user but for the owner of OAuth consumer. That "input" might be the OAuth dance in the browser (e.g. a browser app, or via authorization code grant), or their credentials, or a JWT token in case it's a Connect app.

As long as you keep the refresh token, you can use just it along with client ID and secret – without any additional user input – to obtain a short-lived access token and authenticate your requests against Bitbucket.

Hope this makes sense.

Cheers,
Daniil

In other words, if I have to store the client ID and client secret somewhere in order to use a refresh token, why bother with refresh tokens?

There are many use cases, but one of them is that a third party application, if the user gave consent beforehand, can act in the system on user's behalf without ever storing real credentials of that user and allowing the user to revoke such consent for that app to impersonate them at any time. Refresh token is a per-end-user secret that would give the app such permissions. If the user revokes their consent, refresh token expires, and no new access tokens can be obtained using it.

If the app loses refresh token, it won't be able to get a new one without "asking" the user again. There're some shortcuts there, but nevertheless the user would need to take some action.

So, client ID and secret are essentially credentials authenticating that app against Bitbucket while refresh token is a secret allowing that app to obtain access token to access data of a user (2LO) or to impersonate a user, e.g. act on their behalf (3LO).

Cheers,
Daniil

Suggest an answer

Log in or Sign up to answer
TAGS
Community showcase
Published in Bitbucket

Powering DevOps with Bitbucket Server & Data Center

Hi everyone, The Cloud team recently announced 12 new DevOps features that help developers ship better code, faster   ! While we’re all excited about the new improvements to Bitbucket ...

1,892 views 0 7
Read article

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you