shopify-app-template-node
shopify-app-template-node copied to clipboard
Access denied when using GQL urlRedirects even though read_content scope was added
Issue summary
- Issue found after using
shopify app create node
to create a new public app - Created a new GQL query for
urlRedirects
after updating.env
to includeread_content
as per documentation. - Response was
undefined
but if you query using Admin REST instead, then it's fine
Expected behavior
Expected to receive nodes
of URLRedirect
Actual behavior
After inspecting network requests, got a 200 but response with an error of Access Denied
I've console logged my dev store on server/index.js
to see what the access scope is and got the following which included the read_content
{
'gql-access-scope-issue.myshopify.com': 'write_products,write_customers,write_draft_orders,read_content'
}
But to make sure, I've also ran an app
GQL query to see what the requestedAccessScopes
were but strangely got an empty array.
{
"__typename": "App",
"requestedAccessScopes": []
}
Here's the error from making a GQL urlRedirects query
{
"data": null,
"errors": [
{
"message": "Access denied for urlRedirects field.",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"urlRedirects"
],
"extensions": {
"code": "ACCESS_DENIED",
"documentation": "https://shopify.dev/api/usage/access-scopes"
}
}
],
"extensions": {
"cost": {
"requestedQueryCost": 102,
"actualQueryCost": 2,
"throttleStatus": {
"maximumAvailable": 1000,
"currentlyAvailable": 998,
"restoreRate": 50
}
}
}
}
Steps to reproduce the problem
- Create a new node public app using
shopify app create node
- Update the
.env
to addread_content
toSCOPES
- Do
shopify app serve
and add the app to a dev store - Accept/Allow for the permissions on installing the app
- Check that everything works for the example
ProductsCard
with the create 5 products mutation. - Create a new redirect on your store.
Online Store -> Navigation -> View URL redirects
- Add the following to
ProductsCard
or anywhere really...
const GET_REDIRECTS = gql`
query getRedirects {
urlRedirects(first: 100) {
nodes {
id
path
target
}
}
}
`;
const { data: redirectsData } = useQuery(GET_REDIRECTS);
console.log("GET REDIRECTS", redirectsData);
- Refresh or wait for HMR and see the console.
- Again, expect
nodes
but the actual response should beundefined
withAccess Denied
on network request
Additional Information
If you do the same thing but use the REST API instead, then it works but I prefer GQL - lol.
Add the following.
Add to server/index.js
app.get("/redirects", verifyRequest(app), async (req, res) => {
const session = await Shopify.Utils.loadCurrentSession(req, res, true);
const { Redirect } = await import(
`@shopify/shopify-api/dist/rest-resources/${Shopify.Context.API_VERSION}/index.js`
);
const data = await Redirect.all({ session });
res.status(200).send(data);
});
Add to ProductsCard or anywhere
const getRedirects = useCallback(async () => {
const res = await fetch("/redirects").then((res) => res.json());
console.log(res);
}, []);
useEffect(() => {
getRedirects();
}, []);
On refreshing the app and checking console
The response but I've removed some privacy sensitive stuff and you can see the one redirect I've set up at the bottom.
[
{
"session": {
"id": "REMOVED",
"shop": "gql-access-scope-issue.myshopify.com",
"state": "REMOVED",
"isOnline": true,
"scope": "write_products,write_customers,write_draft_orders,read_content",
"expires": "2022-06-05T19:18:11.962Z",
"accessToken": "REMOVED",
"onlineAccessInfo": {
"expires_in": 86399,
"associated_user_scope": "write_products,write_customers,write_draft_orders,read_content",
"session": null,
"account_number": null,
"associated_user": {
"id": "REMOVED",
"first_name": "gql-access-scope-issue",
"last_name": "Admin",
"email": "REMOVED",
"account_owner": true,
"locale": "en-GB",
"collaborator": false,
"email_verified": false
}
}
},
"id": "REMOVED",
"path": "/item/1",
"target": "/items/1"
}
]
Reduced test case
Just the above through creating a fresh node public app
Specifications
- Browser: Chrome Version 101.0.4951.64 (Official Build) (arm64)
- Device: Macbook Pro, M1 Max
- Operating System: macOS Monterey Version 12.2
I am able to replicate this and it is odd, it may be a bug in the gql api rather than this application. Very good replication steps, thanks. Either the redirect requires a different undocumented scope, or the gql api is interpreting the scopes incorrectly. That's the only 2 ways I think you would get a 403 back from gql with the correct scopes
This issue is stale because it has been open for 90 days with no activity. It will be closed if no further action occurs in 14 days.
We are closing this issue because it has been inactive for a few months. This probably means that it is not reproducible or it has been fixed in a newer version. If it’s an enhancement and hasn’t been taken on since it was submitted, then it seems other issues have taken priority.
If you still encounter this issue with the latest stable version, please reopen using the issue template. You can also contribute directly by submitting a pull request– see the CONTRIBUTING.md file for guidelines
Thank you!
Hi there, this issue is still very much open, above query still does not work in GQL.
@Michael-Gibbons I'm not sure if you're still watching this, but this is still an issue as of 2024-02.