Token doesn't work after netlifyIdentity.refresh() until page reload

I am using netlify identity widget for content protection. Issue is that after 1h access token expires which can be refreshed by built-in method like

netlifyIdentity.refresh().then(token => console.log(token))

But issue is that it doesn’t work until page is reloaded which is not expected behavior for user.
User open page and if token expires page will reload again to apply refreshed token.

Probably, but it’s expected behaviour for Netlify. When you requested the page, the token was invalid (expired), so we sent the 401 page. Now since you requested the token using javaScript, there’s no way for the Netlify server to detect this change and refresh the page for you. The solution? You can do this:

netlifyIdentity.refresh().then(token => {
  location.reload()
})

So better approach should b e like this

if (netlifyIdentity.currentUser().token.expires_at < new Date().getTime()){
  netlifyIdentity.refresh().then(token => location.reload())
}

netlifyIdentity.currentUser().token.expires_at < new Date().getTime() will check if token has expired or not. Right?

Again, that happens on the client-side, not server-side, so you still need to manually reload the page using JavaScript.

Yes. But it’s better to do it only if token has expired

Yeah I mean, issuing a new token every time is not going to cause any issues.

The odd part is, I wonder why you need to fetch the token yourself. I believe the Identity Widget does this by itself.

It doesn’t. I’ve been fixing this and authorization was failing. On function side I’ve

const { identity, user } = context.clientContext
// then return not allowed if not authorized 
if (!user) return { statusCode: 401, body: JSON.stringify({ message: 'You\'re not authorized.'}) 

// preforms db query

So I’m stopping users from accessing without auth. If I don’t do netlifyIdentity.refresh().then(e => console.log(e)) then and reload browser manually it doesn’t work as new token is required to pass.

Is this way of protecting user from accessing data not appropriate?

This way is appropriate, but I believe there’s something else happening. Netlify Identity Widget is being used on various other sites of our own and the token is always automatically refreshed. That’s the only reason we developed the widget so that users don’t have to worry about the GoTrue and its connections. I have manually tried to replicate what the widget does and it’s too much of an effort for a project that quickly needs to add auth to their site.

I can imagine that your code is calling the Function before the Identity Widget is able to refresh the token and save it in the localstorage.

I’m calling function after currentUser() is validated like

function runAfterAthorization(token) {
 // makes request and other stuff
  fetch('/api/data', { headers: { authorization: `Bearer ${token.access_token}` } })
   .then(response => response.json())
   .then(data => {
      // use data
    })
}

const currentUser = netlifyIdentity.currentUser()
if (currentUser) {
  const validToken = currentUser.token.expires_at < new Date().getTime()
  if (validToken) netlifyIdentity.refresh().then(e => console.log(e))
  runAfterAthorization(currentUser.token);
}

This is the current implementation. If I don’t update token manually request fails. :cry:

I hope now you can better assess if code running before or after identity loaded.

In the above example, obviously the function is being called after Netlify Identity is done processing. You also mention this works. I’m not sure about your previous implementation in which you mentioned that Identity Widget is not automatically refreshing the token.

Since you haven’t shared the site URL, I cannot check that.

No this is the previous implementation which I already been using

I can share login privately via direct message

Wait, I’m confused. You said:

But now you said:

Which one is it?

In short, what I’m asking is, is there a specific deploy in which you were not checking the condition that you have shared above? I assume the code you’ve shared is working, correct?

Yes I said both. Sorry.
Actually I didn’t change anything as everything is same as it’s previously.

Yes code is working. As you said identity widget updates token automatically I said that it doesn’t update in my case and I’ve to do manually. That’s why I showed you code that I do it manually. But issue is browse reload needed.

Hey there, @inamkbmail :wave:

Thanks for reaching out. As Hrishikesh mentioned, we need to see the deploy in which you are not using your custom code snippet. We need to see this in order to understand where the token is not being refreshed automatically. We need to see if the request to the identity API is being made.

If you cannot share this with us, please share an exact reproduction of the issue. This will allow us to debug your issue and escalate it to our appropriate teams.