Refresh Token Renewal Question

So, I have a refresh token and I've read that it will expire after 365 days.


I also read something about preserve_refresh_token https://developer.blackbaud.com/skyapi/support/changelog/shared/2019?_ga=2.134966641.1001231271.1623000047-795857990.1598558045&_gac=1.255477242.1622577922.CjwKCAjwtdeFBhBAEiwAKOIy5wdQlwWKwjnsIMtoA6t3Q4VHgJQ5ca0JIRKfD-2YOXLWp3IOpjQbRxoCd8wQAvD_BwE#august


What I would like to do, is never have to authenticate again (I used Postman to get the refresh token as shown here https://community.blackbaud.com/forums/viewtopic/426/51941 ).


Our app will be making multiple/daily calls to the Sky API.


But my question is this - when I use the refresh token to get a new OAuth token, is that same refresh token preserved as active so I can keep using it as long as I use it within the 365 day window? Meaning the refresh token is good for 365 days past the last time it was used? And then this way I can store the refresh token as an environment variable and always use it in our code?


Or do I need to get a new refresh token every 365 days (or a new refresh token each time I get a new OAuth token with the previous refresh token)? Which then means I will need to update the environment variable that stores the refresh token on a regular basis?


I hope my question makes sense. Thanks for your help!

Comments

  • Chris Rodgers
    Chris Rodgers Blackbaud Employee
    Ninth Anniversary Kudos 3 Name Dropper Participant
    Hey Nathan,


    Your question totally makes sense. Let me clarify `preserve_refresh_token` a little. I've mentioned some of this in a previous thread, but let me pull the relevant parts here for you.


    A single refresh token will only ever be valid for (at most) 365 days. Under a "typical" refresh token exchange (where preserve_refresh_token is not specified), you will receive a new refresh token along with your new access token. Your new refresh token is good for 365 days from the time of the exchange, and your previous refresh token can no longer be used.


    When you use the `preserve_refresh_token` option, you are telling us that you'd like to keep the current refresh token valid. However, that original 365 day expiration is still in place; if the token was set to expire in 244 days before the exchange, it will still expire in 244 days. If you have some automation that you intend to run for more than 365 days, you are simply choosing to delay obtaining a fresh refresh token until a time that you decide is best for your application. For this reason, if you are able build your app to accept a new refresh token on each exchange, that will be simpler in the long run. However, we understand that is not possible for everyone depending on architectural considerations/trade-offs (e.g. not being able to programmatically store the new refresh token is definitely one of those cases).

    (Just a little more commentary... Taken directly from that previous thread)

    The typical use case where we've seen this 'preserve' mechanism work best is for apps that perform some kind of daily batch process where the processing is distributed out to multiple 'independent' servers/threads. Before the job begins, the app will exchange the current refresh token for a new access token + new refresh token, and that refresh token will be communicated out to the various nodes of the system. At that point, each node can use preserve_refresh_token so it doesn't invalidate the refresh token for the other nodes.


    In this scenario, the refresh token is only ever as old as the previous job run (e.g. 1 day). That's just one implementation of course, but it's clean in that there is an obvious opportunity to rotate the refresh token. I believe that is where this option works best. I would advise against using 'preserve' to avoid having to handle a new refresh token in general, but I know many apps that are essentially scripted jobs that simply need a refresh token and the developer has the flexibility to manually update that refresh token after a year. Not all apps will have that flexibility or obvious rotation opportunity and trying to manage the timing of manually acquiring and storing a new refresh token may be more complicated than simply handling a new refresh token each time. So, it's definitely not a one-size-fits-all solution and its use will likely be dictated by (or might itself influence) how the app is architected.

    Hope this answers your question. Let me know if not.
  • Thanks Chris Rodgers‍ That makes sense.


    So where to people typically store the refresh token if not in an environment variable (since it changes all the time)? Would we be fine just storing it in our database?


    I was originally thinking about the security risk, but I guess since we also have our client_id and client_secret as environment variables - maybe the refresh token doesn't really need to be protected like I was thinking?


    EDIT:

    We went ahead and stored the token and refresh token in our database and that has worked well.

Categories