lens-sdk: Get a refreshed access token if expired

Is your feature request related to a problem? Please describe.

To authenticate a user against my Rest API, I forward the Lens access token and send it to my server, then call the Lens API to verify that it’s valid. This process is working fine as recommended by the lens docs. To get the access token, I use the useAccessToken hook but that returns the current accessToken that might be expired, I need a way to get a refreshed access token.

Describe the solution you’d like

I guess smth like the following would solve my problem

const {getAccessToken} = useAccessToken()

const myFunc = async () => {
  // SDK would get a new access token if expired from the refresh token 
  const validAccessToken = await getAccessToken()
  callMyAPI(validAccessToken)
}

About this issue

  • Original URL
  • State: closed
  • Created 5 months ago
  • Reactions: 1
  • Comments: 29 (18 by maintainers)

Most upvoted comments

@cesarenaldi did a quick test and it seems to be working, I guess we can close the issue and reopen it in case the issue appears again?

authenticateWith was born for a very specific use case: a Lens app that has its own API integration and needs to create a LensClient instance out of a Refresh Token. So that’s why currently there is no React SDK counterpart. But it’s easy to create an hook, we already have useAccessToken and useIdToken hooks. Adding a useRefreshToken is pretty quick.

In the meantime you could extract the refresh token by accessing the client storage use in the React SDK. Either you create it using whatever underlying mechanism you like for the client and you pass it around, or you rely on the default (i.e. leverages window.localStorage) and use the useStorage hook to get hold of it.

Once you have storage, you call:

const item = storage.getItem('lens.development.credentials');

const content = JSON.parse(item);
const refreshToken = content.data.refreshToken;

Notice the item label contains the environment name (development or production) so it differs depending on your LensConfig setup (this was done mostly to avoid annoying clashes/error during the development experience).

Regarding:

What’s your opinion on using React Hooks AND the client, would this complicate authentication further? We made is so it’s possible to have them working in the client side-by-side, but this is meant either for token-gated support or for very remote cases where a feature is available on the LensClient but didn’t make it to the React SDK (yet).

Just added you to the TG group. Feel free to DM me to discuss details further.

This NextJS doc page gives some insights when they talk about Serverless Node.js and raises the same concern about boot up time: https://nextjs.org/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes

So I guess, it depends on the way you run it.

As instantiating a LensClient is not expensive your could encapsulate all the decision making around isDev into a factory function:

function createLensClient() {
  return new LensClient(...);
}

and use such function to create an ephemeral instance in the API route handler or a middleware for it.

@b-bot sorry for editing my previous comment, there were imprecisions @krzysu made me realize. For all intent and purposes the LensClient refresh credentials if the internal refresh token is still valid.

The persistent storage is likely to play a role in you use case but still need to understand what Profile you expect to log-in with on either sides (BE and FE).

@pradel a fix for this in the next release.

BTW, the approach you suggested is probably better IMO, just didn’t want to introduce an API breaking change as I am aware several teams rely on the useAccessToken hook.