Expired Token - access token 403 error on some page visits, Safari

In the security bit? this is what we have (I think it's default?)

OK, Thanks.

Is there any way you can send me your project so I can test this on my side?

Yes, would zip email be ok?

Yes, that works. You can send me a private message by clicking my name here.

Morning Phil,

Hope you're well

We've narrowed this down to content updates in Prismic, regardless of browser or Incognito. Updating any content seems to cause some pages to 403 unless you refresh. This can happen on iPads, testing browsers or dev localhost:3000, it doesn't matter if you're signed into Prismic or not.

Thanks
Jake

Could it be that our Vuex nuxtServerInit Prismic calls are expiring when the content is updated?

Hi Jake,

I'm good, you're well too.

It sounds like that could be it. I just had a look at your project and I can't say I totally understand what you're doing, but I imagine doing your queries for your pages in your vuex store before the build would cause this issue as your master ref expires after you publish in the dashboard. The master ref changes every time a page is published, which is why we don't recommend caching of the calls etc.

You would need a webhook to trigger a fresh rebuild to get around this or only do your calls in the page itself. If you use nuxt's full static mode it shouldn't slow things down either.

Thanks.

Hey Phil,

Most page calls happen on per page visit. It's only the microsite list documents that we pull in globally as the information is used for various linking through methods (not direct links) and the enquiry features; I didn't want to fetch this information for every page and the nuxtServerInit method seems like a good solution to only load it once.

I will look at moving these to an API call on component basis rather than on initial load with nuxtServerInit.

Thanks for your help with this.
Jake

1 Like

You're welcome, you got there before I did anyway.

Let me know how it goes. I'll be here for any further questions.

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Hi Phil,

We've been investigating this a bit more as moving the calls out of nuxtServerInit didn't seem to help and have been able to replicate this using the starter nuxt project (Built using this tutorial - Configure Your Project with Nuxt.js - Prismic)

We can see the 403 error happening on the client side when there are prismic api calls in async data at a page level.
e.g.
async asyncData({ $prismic, params, error }) {
try {
const document = await $prismic.api.getByUID("page", params.uid);
const result = await $prismic.api.query(
$prismic.predicates.at("document.id", document.id)
);
return {
result,
document
};
} catch (e) {
console.log("caught error", e);
error({ statusCode: 404, message: "Page not found" });
}
},

It looks like the prismic api is storing the master ref and uses that same master ref for the rest of the client session. So if a document is published after a user has loaded a page, and traverses the site using router links, any subsequent api calls use the original stale master ref, and the master ref doesn't ever seem to be updated.
So if the client is left for a period of time (it seems to be around 5-10 minutes as I think the old ref call is cached for a period), then a client side prismic api call is made using an old master ref, it seems like the old ref has expired and throws the 403 error.

Steps to replicate:

  1. Clear cache on browser. Load a page (I created a few pages with links to other pages)
  2. Make a few publishing updates so that the master ref is updated
  3. Wait 10 minutes (normally 5 is enough but 10 to be safe :))
  4. Without refreshing the page click on links to a few pages (that has api calls in it).

It feels like the prismic api helper should potentially catch this and update the master ref if stale? Or is there a way when we catch the error to get the $prismic.api to refresh?
Hopefully the above is clear!

Thanks,
Will

Hi Will,

Welcome to the community!

Thank you for clarifying and testing this. This is strange because as you say...

Which it should. I followed your instructions but wasn't able to recreate the issue unfortunately.

How are you deploying your NuxtJS application?

Thanks.

Hi Phil,

Thanks for the reply, for the testing I was doing, I was running it in development mode "npm run dev".

When you tested did you see the master ref update in the calls made to the api from the client side after publishing? Should they update as soon as there is a new master ref available? Or does the prismic api helper catch the 403?

From my testing they never update, and only tend to work either because the browser is caching the old call and/or prismic is caching the old call or if we do a hard refresh.

Thanks!

Have you been able to reproduce this in production? Because if you are deploying statically then there will never be the question of conflicting master refs in the browser.

So this is most likely just an issue in dev as you're doing a lot of updates and users' browsers might have the old ref they don't refresh. Though you're right we should have some sort of mechanism in the @nuxt/prismic kit that checks to see if the ref is the most up to date one and triggers a refresh.

I've created an RFC for this in the kit so that the developers are aware of this:

Thanks Phil,

This happens on our SSR production site, the site isn't live yet but the near-live test also throws this error.
Unfortunately static generated isn't really an option given the projects phase 2 plans.

OK, normally it's still not an issue in SSR unless you're doing a lot of contents updates at the same time as I imagine you're doing now.

All the same I don't want to leave you with an issue like this so I'm reaching out to my team to try and find a solution for you.

Thanks Phil,

We have built in a fallback which forces a full page reload if refs are different. Obviously this isn't ideal as it leads to a longer load time to the new page, but at least removes the 403 error.

We put this inside our layouts/default.vue

async middleware ({ store, params, $config, redirect, route, $prismic, $axios }) {
  const currentMasterRef = $prismic.api.masterRef.ref
  const freshMasterRef = await $axios.get('https://[repo].cdn.prismic.io/api/v2')
  if (process.client && currentMasterRef !== freshMasterRef.data.refs[0].ref) {
    redirect($config.baseURL + route.fullPath)
  }
}

I was going to suggest something similar for the time being, though not as well coded as your example :laughing:

I've made the team aware of this and they'll investigate further.

1 Like

This is being tracked as an open feature request.

If you have another use-case for this feature, you can 'Flag' this topic to reopen. Please use the :heart: button to show your support for the feature and check out our Feature Request Guidelines.