Hey, I followed the post on the new cookieless authentication for Shopify app bridge. I’m trying to make a billing charge when a user takes an action on my app for example a button click should then go to the confirm payment action page. (Sidenote: this is a pretty terrible UX pattern, is there another way to do this like a modal within the embedded app or something? Looks terrible to have to redirect to an entirely different page, confirm the action and then reload the site on the return url) But anyways, I set up the the embedded app, get authentication confirmed etc, and when trying to use a graphql mutation with apollo client, the response is giving the error: “Error: Network error: Unexpected token < in JSON at position 0”. I’m assuming this is from an html file being returned instead of JSON. I know that this is a common apollo issue, but I’m hoping for some answers to why the issue is occurring in the first place. Postman requests seem to be working fine, and the main change has been the cookieless authentication using authenticatedFetch from the new app bridge utils package. My set up is a bit unusual with authentication being done through a series of firebase functions calls but the app is being loaded properly in the embedded format. When a shop owner goes to the main shopify app page, the app bridge instance is created and the apollo client is being created as outlined in the new cookieless authentication post.
My graphql mutation is a pretty simple create one time charge mutation.
My component uses the outlined tutorial format for the app-bridge-react and apollo wrappings.
The button calls the mutation here:
I cannot for the life of me figure out what went wrong and the fact that the apollo client errors are html and unloggable doesn’t help. Can anyone point me in the right direction for what’s happening here. Any info on the issues with the general set up, issues/documentation on authenticatedFetch, or even the best ways to investigate html error responses from Apollo would be greatly appreciated. Thanks!
Hi @stheticsoftware
Can I have your appId? “Unexpected token < in JSON at position 0” This error could happen when embedded app uses App Bridge but the host is still EASDK.
Hey thanks Henry, my AppID is: eeecdd09e49df1307834481f5d10dbf8
Hi @stheticsoftware
The authenticatedFetch will retrieve sessionToken and put it to header Authorization: Bearer session-token-from-authenticated-fetch. You need to use retrieve bearer token and validate it in your server. Are you doing it?
“Postman requests seem to be working fine”
=> What’s this request?
“My set up is a bit unusual with authentication being done through a series of firebase functions calls but the app is being loaded properly in the embedded format.”
=> Did you retrieve bearer token in Firebase functions? How do you perform graphql mutation in the server? What token did you use?
Thanks for the info again. Im retrieving and validating the shopify access token and setting headers as “X-Shopify-Access-Token”: shpat_xxxxxxxx. I take it that this is not the proper access token to retrieve/store? I know the JWT is a different format, but is that retrieved in a similar way to the POST request to "https://${shop}/admin/oauth/access_token"? As for the Postman request thats just to make sure the api calls are formatted correctly/returning proper data. www.postman.com . I’m not sure if I’m properly retrieving/using the bearer token, as I’m using the access token provided by the POST request to "https://${shop}/admin/oauth/access_token" and then signing calls with the “X-Shopify-Access-Token” header. Here’s an examplpe of a working api call from the server:
Hi @stheticsoftware
I think there is a confusion between new sessionToken (for cookieless) https://shopify.dev/tools/app-bridge/authentication and accessToken from original Shopify auth https://shopify.dev/tutorials/authenticate-with-oauth. They are two different token.
-
The accessToken is used to perform graphql call on your server. This is obtained during app installation.
-
The sessionToken is only meant for validating the request coming from your app loading inside Shopify. It cannot be used as X-Shopify-Access-Token.
Thanks,
Perfect, thanks! So as I understand, we don’t necessarily need to use the sessionToken or cookies as long as we have other methods of validating communication between front-end and server. And the accessToken on the server will continue to work as expected?
we don’t necessarily need to use the sessionToken or cookies as long as we have other methods of validating communication between front-end and server.
Correct. However, I am curious how you validate the communication. Would you mind to share it as well? Thanks.
Sure, during the initial authentication process, we have the firebase functions also create a custom firebase authentication token that is passed back to the client. The client is signed in with that custom token. All communication after that is done with firebase function triggers to the database (ie. the client updates their database document which has rules to only allow the user to write to their own document, then the functions listen for updates to the documents and make the api calls). The custom token changes with each sign on as well. We’re considering adding in some more security at some point, perhaps encrypting the tokens in transit and having the individual’s secret key stored in their personal database document or something. Please let me know if you have any other suggestions or flaws you can think of!
It sounds to me that you are using Login with Google for the initial authentication. If so, I would suggest to enable Block third-party cookies in the browser and test the flow again.
Yep, it all works with cookies blocked. It’s not actually google login, its called firebase custom tokens https://firebase.google.com/docs/auth/admin/create-custom-tokens its a pretty cool authentication method. The functions/server generates an access token that lives for an hour. They’re actually still JWT like the Shopify session tokens. I’m curious how you guys recommend passing JWT to the client side. From what I’ve seen there’s still a bit of a debate going on between passing with web/session storage vs cookies.
Here’s some of the code for anyone else doing trying to do auth/api calls in this way. I’d love some feedback on the security of this!
On the app entry point link, it goes to my react app which has a route method to call this firebase function:askForPermissions
After the ask for permissions completes, it’s redirected to confirm install here which is where we create the firebase token and create the user database document if there isn’t one already.
My main security concern here is passing in the firebase take in the url.
Then on the front end, we retrieve the firebaseToken and sign in the shop user with that.

All further api calls are made from the firebase functions/server when a user writes to their database document. The database rules only allow for a person to write to the database document associated with the user they are signed in as.

Hope this can help some people!
Hi @stheticsoftware
IMO, I think the way you are using firebase custom token is insecure. The problem is that untrusted clients could receive custom token from the server. There are two things we need to verify:
- 1st: Shopify and the client.
- 2nd: the client and the server.
I could be wrong in the way your app is setup. However, I only see two options to clarify your app coming from Shopify: cookies or ask Shopify at runtime through new sessionToken. The firebase custom token is only for verifying client and server connection.
Hi @stheticsoftware
Because you just provide extra information. I think your setup is fine. However, the UX is not nice because the app performs auth redirect every time merchants open it. Both cookies and new sessionToken are supposed to deal with UX of subsequent app opening request.
Hey @Henry_Tao I really appreciate the feedback. From what I understand from the shopify oauth flow, doesn’t the extra information like the HMAC, nonce, and authorization code validate that the requests are coming from an authorized shopify client? I’m definitely with you on the UX patterns though haha, in my initial post I also mentioned this, it’s a pretty bad flow especially when making one time app charge redirects. We bill a calculated variable charge each time a user takes a certain action on the site and have to redirect to confirm each time and lose place in the app which is pretty rough.
Hi @stheticsoftware
You are right about HMAC. It can be used to verify the request coming from Shopify. However, HMAC has a couple of limitation:
- It is only available in the first request. A single page app might have problem with validating subsequent requests.
- It is in request query param which can be hijacked very easy. You often need to combine with timestamp to invalidate the request.
The new sessionToken is a better option in term of authentication.
Awesome thanks, yes this was the original meaning of my post. I couldn’t get the authenticatedFetch to work at all, perhaps this new sessionToken would help. Any idea of how to implement this with my set up? Since I’m not using the app gem, the documentation says to obtain the sessionToken manually here https://shopify.dev/tools/app-bridge/authentication but I’m unclear where exactly the session token is coming in, where/how to decode it since the appBridge set up was not working.The docs mentioned calling an appbridge action to get the sessionToken but I couldn’t find the specific docs on that.
Just for some more info I tried doing this:

but couldn’t get the promise to resolve so I gave up.
Hi @stheticsoftware
Please check below steps:
-
The authenticatedFetch retrieves sessionToken and appends it to request header in the form of Authorization: "Bearer " + sessionToken. Check https://cdn.jsdelivr.net/npm/@shopify/app-bridge-utils@1.26.2/utilities/session-token/authenticated-fetch.js and https://shopify.dev/tools/app-bridge/authentication#when-youre-done
-
When the request hits your server, you need to look for Authorization header, extract sessionToken, and validate it. Check https://shopify.dev/tools/app-bridge/authentication#obtain-session-details-manually and https://shopify.dev/tools/app-bridge/authentication#verify-the-signature
-
If you don’t use Apollo, you can use getSessionToken promise in app-bridge-utils utils instead. It will returns a sessionToken whenever you call it. Check https://shopify.dev/tools/app-bridge/authentication#use-session-tokens-with-axios
I hope it helps.
Hi @stheticsoftware
It’s a promise, you cannot do console.log directly. Try this:
const sessionToken = getSessionToken(window.app);
sessionToken
.then((token) => {
console.log('This is my token', token);
})
.catch((error) => {
console.log('Something wrong happens', error);
});