We have been using Jira OAuth 2 (3LO) for a while now and it has been working quite well. Recently, we started looking at the performance side of things and have been studying the docs on OAuth2 (3LO) to understand where we can make improvements to our implementation. While doing so a bunch of questions came up and I am wondering how others do certain things or what’s the intended use.
I am just posting a big list here and would be happy to start a discussion/get some feedback.
1. What data should we store from the authorization flow?
From what I understand, at the very least you should store the refresh_token
from the initial request to POST auth.atlassian.com/oauth/token
in a persistent store because this will allow you to fetch a new access token later. The access token itself could go e.g. in a Redis cache and expire based on expires_in
value. If there is no access token in the cache or an API call returns 401
we could re-try the API call after refreshing the access token using the stored refresh token.
2. How to make API calls efficiently?
The docs suggest to first make a GET request to api.atlassian.com/oauth/token/accessible-resources and then to
Find your site in the response and copy the
id
. This is thecloudid
for your site.
even more confusing/complicated at the end of section 4 it says
Note, the
id
is not unique across containers (i.e., two entries in the results can have the sameid
), so you may need to infer the type of container from its scopes.
This poses two questions:
- Does that mean every API call requires two actual API calls?
- How are we meant to “find” the site that we/the customer wants to use?
Here but this is what we did:
After making the initial call to auth.atlassian.com/oauth/token
we make a call to api.atlassian.com/oauth/token/accessible-resources
. If there is only one site we store it in the persistent store together with the refresh token (see the first question). If there is more then one site we will ask the user in the UI which site he wants to use on the first API call - then update the persistent store with that site. Now we don’t need to make the additional call to get accessible-resources
on every API call. Not sure if that’s a good idea but so far it has been working. Curious how others deal with this.
3. Why and when to check site access for the app?
Section 4 in the docs describes a process to check site access when calling a site’s API. From what I understand the idea is to call the accessible-resources
endpoint before you make the actual API call. I am not quite sure though what you should do with the response other than getting the id
/cloudid
. Should we check if the scopes of the site we want to call match the scopes granted in the initial authorization response? And, why should we check this every time we call the API?
4. What do API response payloads look like (in particular error response payloads)?
We’d be interested to know what API responses we would have to expect and what they look like. I think we are quite clear about the success case but wonder what error status codes to expect from different OAuth API endpoints (/oauth/token, /accessible-resources) and what payloads we can expect. E.g. we found that an error response from POST auth.atlassian.com/oauth/token
returns a JSON with {error: "...", error_description: "..."}
but it would be good to have better docs on what status we should handle and what error payloads are meant to look like.
Any feedback on these points would be highly appreciated