GraphQL 401 Unauthorized when using app proxy

When ever I try to call the GraphQL API from my app proxy, it returns a 401 Unauthorized error. Things I’ve tried:

  • Making sure I’ve got the correct scopes
  • Using admin and storfront from authenticate.public.appProxy
  • Removing the GraphQL related code to see if my app proxy page renders (it does)
  • Using shopify app dev --reset

Here’s my Remix app proxy route:

import { LoaderFunctionArgs } from "@remix-run/node";
import { authenticate } from "../shopify.server";

export async function loader({ request }: LoaderFunctionArgs) {
  const { liquid, admin } = await authenticate.public.appProxy(request);

  if (!admin) {
    return new Response();
  }

  const response = await admin.graphql(
    `#graphql
    query firstProduct {
      products(first: 1) {
        edges {
          node {
            title
          }
        }
      }
    }`,
  );

  const body = await response.json();
  const title = body.data.products.nodes[0].title;

  return liquid(`${title}`);
}

Here’s a couple things you could try:

1. Verify the JWT Authentication

  • Ensure that the x-shopify-request-jwt header is being validated correctly in your app proxy route. This JWT is signed using your app’s secret key and contains claims that verify the authenticity of the request.
  • Use a library like jsonwebtoken to decode and validate the JWT. Check for:
    • Valid signature using your app’s secret key.
    • Expiry (exp claim) to ensure the token hasn’t expired.
    • Matching method, url_sha256, and headers_sha256 claims with the incoming request.

2. Check Access Token and Scopes

  • Ensure that the access token used in the admin.graphql call has the required scopes for the query you are making. For example, to query products, you need the read_products scope.
  • If you are using online access tokens, remember that they are tied to a user’s session and expire after 24 hours or when the user logs out. Ensure you are refreshing or re-authenticating as needed.

did you get it sorted?

Yes! Deleting the session from my Prisma DB and revisiting the admin page resolves the issue. I’ll investigate further to see if the token is refreshing but the session isn’t updating in the database. For now, deleting the session is a workaround.

how does your app proxy work from a dev store? any workaround?