Access Token Renewal

246 views
Skip to first unread message

Joseph Anderson

unread,
Jan 17, 2017, 10:35:39 AM1/17/17
to Lightspeed Retail API Developers
Hi,

My app uses OAuth and the access token:


Does this token need to be renewed? If I don't make any calls to LightSpeed for a few days, does the token expire? If so, how do I renew it? 

Joseph Anderson

unread,
Jan 17, 2017, 10:40:03 AM1/17/17
to Lightspeed Retail API Developers
Hi,

I found these docs:


Does the access token expire every 24 hours?

Michaël Gallego

unread,
Jan 31, 2017, 4:55:58 PM1/31/17
to Lightspeed Retail API Developers
Hi,

I've had a discussion with a Lightspeed support person regarding the way the API authentication is done, I allow myself to post it here as well, as the current authentication really sounds... broken to me.

From what we've heard, here is how it works in summary:

* An access token is valid for 10 minutes
* A refresh token has no validity expiration BUT once it's used to generate a new access token, it is revoked, and you will need to save the new refresh token returned when asking the new access token.

In your case, indeed, if you do not use it for a few days, your access token will become invalid, which means that you'll need to save somewhere the refresh token (which, indeed, make the security argument quite useless as in the case of a long-lived access token or a long-lived refresh token... you still need to save it somewhere in your database... except that it would be much easier to rotate an access token directly in the Lightspeed interface).

This makes this new model extremely hard to use for most apps (and especially apps that are used for a single customer, where the whole authorization process is therefore a bit useless: it would be much easier to simply have a way to directly create long-lived access tokens with reduced permissions, and be able to rotate them on demand).

But most importantly, it makes it extremely unreliable and not user-friendly at all (unless I've missed a complete point in the method).

Imagine the following scenario:

1) You're having an access token from the initial OAuth dance, along a refresh token. So far, everything's good. You can persist the refresh token in database to get a new token once it's expired.
2) The access token has expired => you can use the refresh token to get a new access token... BUT something bad happen. A lot of things can happen:

* You're using load balancing, and one instance is removed from your pool before you had the time to persist the token.
* Your database is temporarily down.
* A concurrent request has also used the same refresh token at the same time, making your second call invalid as the refresh token has expired.
* ...

THIS can happen, and so far the answer from Lightspeed to me has been "you'll need to do something to avoid those problems. Maybe design it so that the token requests are all handled in the same place." So basically the suggestion is to create a whole micro-service to do all this processing, just for generating an access token?

But what happen when one of those issues arise? Well... you're in a stuck state: your new access token will expire in 10 minutes, but you haven't been able to save the new refresh token... so after 10 minutes... well... you just need to ask the customer to re-authorize the app again to run the OAuth dance again, and get a new access/refresh token (not talking about the huge downtime if the customer is not here to do that re-authorization right away).

I honestly can't understand the security advantages that this solution brings, and I must be missing something quite important here. I've used a lot of API over the last few years, and this is the very first time I run through a such convoluted and unreliable system that basically runs under the assumption that "no server nor unexpected errors will occur".

Whenever I had to craete private integration on a given solution, I just had the possibility to create a long-lived token, with a given set of permissions, and a simple way to be able to rotate the key in case of securtiy. This allowed to directly feed the servers with an access token in an environment variables (which make it easier to secure it, and remove all the hassle of storing it in database).

Can someone from Lightspeed enlightens me on that, give some strong options on how to avoid the issues outlined before?...



Michael Carey

unread,
Feb 1, 2017, 10:40:01 AM2/1/17
to Lightspeed Retail API Developers
Hi Michaël,

Just to clarify, access tokens will expire after 10 minutes however refresh tokens will never expire. When an integration is first authorized, an access token and a refresh token will be returned. The refresh token will not expire unless the customer revokes it. This should resolve the concerns you outlined.

Support tested an early implementation of the OAuth workflow where new refresh tokens were generated with each access token request, however this behaviour was changed in the final implementation. We've updated our documentation to reflect the current behaviour:


The primary purpose of enforcing our new OAuth implementation is to improve security for our customers. We understand that there will be edge cases causing an app to loose access until the customer reauthorizes, however this is necessary to achieve the level of security we are aiming for. Long-lived API keys pose a major security risk as they can be copied and shared unwillingly, and their permissions can be altered at any time. With the OAuth workflow, customers can see exactly what permissions an app is requesting and know that those permissions will never change. 

If you have any other questions about the OAuth workflow, please contact us at api.s...@lightspeedhq.com.

Thanks,

Michael Carey

Team Lead - API Integration Specialists

Michaël Gallego

unread,
Feb 1, 2017, 10:46:53 AM2/1/17
to Lightspeed Retail API Developers
Hi !

Thanks a lot for your answer. That's an awesome news :). Thanks a lot for taking into account this feedback.

Just to be sure, if I understand correctly, when I request a new access token using a refresh token, the same refresh token value will be sent as part of the access token renewal request (or will it be another refresh token, but that does not invalidate the old one)?

Michael Carey

unread,
Feb 1, 2017, 11:16:41 AM2/1/17
to Lightspeed Retail API Developers
Hi Michaël,

The refresh token is only returned once. It will be in the response received after authorizing. 

When the integration is first authorized, you will receive the following response:


{
 
"access_token":"{access_token}",
 
"expires_in":10,
 
"token_type":"bearer",
 
"scope":"employee:admin_shops employee:customers systemuserid:1234567",
 
"refresh_token":"{refresh_token}"
}



When using the refresh token to get a new access token, the response will be:


{
 
"access_token":"{access_token}",
 
"expires_in":10,
 
"token_type":"bearer",
 
"scope":"employee:admin_shops employee:customers systemuserid:1234567"
}


I hope that information helps. Let me know if you have any other questions.

Thanks,

Michael Carey
Team Lead - API Integration Specialists

Antoine

unread,
Feb 1, 2017, 1:18:36 PM2/1/17
to Lightspeed Retail API Developers
Hi Michael, curious, how was the 10 minute limit decided? It seems incredibly short. It means that every 10 minutes, one API call would fail with a 401, we'd then have to refresh the access token, then re-issue the original call. The mechanism is fine, but doing this every 10 minutes means a lot of refreshes and a lot of slow calls every day.

Why not a 24 hour delay? surely you won't need to revoke access tokens on a 10 minute notice?
Thanks,
Antoine

Justin Hildreth

unread,
Feb 1, 2017, 1:31:00 PM2/1/17
to Lightspeed Retail API Developers
If your application keeps track of the lifetime of the token it's holding (using the 'expires_in' value that's returned along with the token), you could perform necessary refreshes prior to making requests, avoiding 401s and reissuing http requests. That will be my plan for integrating with the API.

While that doesn't fully address your question, considering that approach might be worthwhile. I'm not sure I necessary agree with there not being a need to revoke access on a tighter timeline than 24 hours - it all depends on your use case though.

Justin

Rafael Sabino

unread,
Feb 25, 2017, 8:16:59 PM2/25/17
to Lightspeed Retail API Developers
Hi, I seem to be getting a 0 in the expires_in field when a request a new token, is that expected behavior right now?  Also, expires_in is the GMT timestamp that marks the expiration time of the token, or is it the number of seconds the token will last?  thanks!
Reply all
Reply to author
Forward
0 new messages