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

Hey Prismic team, hope you're all well!

I've been receiving a 403 error (forbidden) from Prismic api v2. It happens when visiting some page urls, it happens very rarely, but obviously leads to an error page instead of the desired page.

I've narrowed this down to what I believe is the route resolver when not visiting a URL within this route structure:

  • It seems to happens more on Safari, Chrome has happened once
  • It happens on both production/development builds
  • My route resolvers are otherwise working perfectly
  • It has happened on 4 different machines
  • The json error is: {"error":"Access to this Ref requires an access token","oauth_initiate":"https://[repo].cdn.prismic.io/auth","oauth_token":"https://[repo].cdn.prismic.io/auth/token"}

This is the request path URL that throws the error:
https://[repo].cdn.prismic.io/api/v2/documents/search?routes=%5B%7B%22type%22%3A%22journal_post%22%2C%22path%22%3A%22%2F%3Alang%2Fjournal%2F%3Acategory%2F%3Auid%22%2C%22resolvers%22%3A%7B%22category%22%3A%22category_relation%22%7D%7D%2C%7B%22type%22%3A%22ondemand_post%22%2C%22path%22%3A%22%2F%3Alang%2F%3Aondemand%2F%3Acategory%2F%3Auid%22%2C%22resolvers%22%3A%7B%22category%22%3A%22category_relation%22%2C%22ondemand%22%3A%22category_relation.link_to_ondemand%22%7D%7D%2C%7B%22type%22%3A%22press_post%22%2C%22path%22%3A%22%2F%3Alang%2Fpress%2F%3Acategory%2F%3Auid%22%2C%22resolvers%22%3A%7B%22category%22%3A%22category_relation%22%7D%7D%5D&page=1&pageSize=1&lang=en-gb&ref=YEDCXRIAACAAhESY&q=%5B%5Bat(my.page.uid%2C%20%22hamburg%22)%5D%5D

Full 'search' network request:
network request.zip (1.9 KB)

I can send you the Prismic repo in a private message if required.

Any help would be much appreciated.

Thanks
Jake

We've been digging our end and believe it may be something to do with tokens expiring/caching.

Whenever you have a fresh instance of the site it seems to be fine for a while.

When we leave Safari on the homepage for a while and then go to visit a page it will throw this error, but only for some pages, other pages (inc same type) continue to work as expected.

Update: We have now managed to recreate this issue on Chrome.

Hi Jake,

It sounds like you describing an expired preview token. The preview token expires once the saved information has been archived or published. The preview token generated is only valid for the information being previewed at that time.

So this means you need to make sure you exit the preview by clicking the purple 'X' button when you're doing viewing a preview of the cookie will still be in your browser and cause this issue.

Thanks.

Hi Phil,

Thanks for getting back to me.

This happens outside of Previewing, when not signed into Prismic. For example I do not use Safari as a browser for anything other than testing, I have not used Prismic on it or viewed preview links. This has also happened in Incognito when viewing our development site and running the application under localhost:3000.

Safari private session running localhost:3000 with the error.

/en/journal/ would otherwise work, I can load that same page in another window.

Thanks

Hey,

No worries. Thanks for clarifying. Is your repository set to private?

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: