kinngh / shopify-node-express-mongodb-app

An embedded Shopify app starter template made with Node, Express, React and Vite, with all the required stuff hooked up.
https://x.com/kinngh
MIT License
276 stars 92 forks source link

Shopify API Error: "400 Bad Request" #135

Open adventuretocode opened 4 weeks ago

adventuretocode commented 4 weeks ago

Thanks @kinngh Thanks for the latest version's "Managed Installation Update." It's greatly appreciated! Thanks for the latest code version. The repository is working fine with the app installation.

I am encountering an error while trying to perform a token exchange using the Shopify API. The error response I receive is a 400 Bad Request with the message invalid_subject_token. Below are the relevant details and code snippets that lead to this error.

`---> An error occured in isInitialLoad HttpResponseError: Received an error response (400 Bad Request) from Shopify:
If you report this error, please include this id: be373ff8-3fdb-4a5e-b887-efb7a832b9b7-1717770139
    at throwFailedRequest (app_code/node_modules/@shopify/shopify-api/dist/esm/lib/clients/common.mjs:106:19)
    at Object.tokenExchange (app_code/node_modules/@shopify/shopify-api/dist/esm/lib/auth/oauth/token-exchange.mjs:36:13)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async isInitialLoad (app_code/server/middleware/isInitialLoad.js:13:43) {
  response: {
    code: 400,
    statusText: 'Bad Request',
    body: {
      error: 'invalid_subject_token',
      error_description: 'Token exchange cannot be performed due to an invalid subject token.'
    },
kinngh commented 4 weeks ago

Thank you!

Can you also post in the code for the file? Also, is this happening in dev only or is prod also affected? I know it does throw the JWT error in dev mode and it's fine to ignore, but haven't seen this one yet

adventuretocode commented 4 weeks ago

@kinngh I am using the latest repo. There are no changes in the code on my end. This happened in both dev and prod. I am not sure where things are breaking.

If you need further clarification or adjustments, please let me know!

kinngh commented 4 weeks ago

@adventuretocode let me try and see where this is breaking - I know in dev mode you're gonna see some breaks because of URL params missing and that's fine, but in prod it works just fine because HMR doesn't trigger token exchange.

Can you please update your isInitialLoad.js to this one filled with console logs so it's easier to catch it?

import { RequestedTokenType } from "@shopify/shopify-api";
import StoreModel from "../../utils/models/StoreModel.js";
import sessionHandler from "../../utils/sessionHandler.js";
import shopify from "../../utils/shopify.js";
import freshInstall from "../../utils/freshInstall.js";

const isInitialLoad = async (req, res, next) => {
  try {
    const shop = req.query.shop;
    const idToken = req.query.id_token;

    if (shop && idToken) {
      console.log("Fetching Offline Tokens");
      const { session: offlineSession } = await shopify.auth.tokenExchange({
        sessionToken: idToken,
        shop,
        requestedTokenType: RequestedTokenType.OfflineAccessToken,
      });
      console.log("Fetching Online Tokens");
      const { session: onlineSession } = await shopify.auth.tokenExchange({
        sessionToken: idToken,
        shop,
        requestedTokenType: RequestedTokenType.OnlineAccessToken,
      });

      console.log("Saving Offline Tokens");
      await sessionHandler.storeSession(offlineSession);
      console.log("Saving Online Tokens");
      await sessionHandler.storeSession(onlineSession);

      console.log("Registering Webhooks");
      const webhookRegistrar = await shopify.webhooks.register({
        session: offlineSession,
      });

      console.log("isFreshInstall Search");
      const isFreshInstall = await StoreModel.findOne({
        shop: onlineSession.shop,
      });

      if (!isFreshInstall || isFreshInstall?.isActive === false) {
        // !isFreshInstall -> New Install
        // isFreshInstall?.isActive === false -> Reinstall
        console.log("Running is fresh install");
        await freshInstall({ shop: onlineSession.shop });
      }

      console.log("Webhooks");
      console.dir(webhookRegistrar, { depth: null });
      console.log("Done with webhooks");
    }
    console.log("Middleware done");
    next();
  } catch (e) {
    console.log(`---> An error occured in isInitialLoad`, e);
    return res.status(403).send({ error: true });
  }
};

export default isInitialLoad;
adventuretocode commented 3 weeks ago

@kinngh Thank you so much for the solution provided earlier; it was really helpful. However, after replacing the file isInitialLoad.js, I can see the log is working fine.

Could you please assist me in resolving this? I am attaching the app screenshot. I am running the app in Dev mode.

Here are the steps I followed:

git issue - Sc - Screenshot from 2024-06-10 16-50-32

git issue - Sc - Screenshot from 2024-06-10 16-50-50

  1. Set up a fresh app with new node modules.
  2. Started the Cloudflare tunnel using $ npm run cloudflare.
  3. Added the URL into .env and verified all the .env values are correct.
  4. Ran $ npm run update:config.
  5. Ran $ npm run dev.
  6. App installation is working fine.
  7. The App Billing API debug/billing plan activation redirect is not working. The redirect URL is api/auth?charge_id=23*****8910. Can you please help me with the redirect to the app's main page? git issue - Sc billing redirecting  - Screenshot from 2024-06-10 16-50-50

I can see the debug card is working fine now, but it creates an issue after 1-2 days when the app user does not have access to the app. Thank you for your assistance.

kinngh commented 3 weeks ago

Fixed in https://github.com/kinngh/shopify-node-express-mongodb-app/commit/2d4717b81406225cbf1f41ac0d4cbdbc67941311

kinngh commented 3 weeks ago

@adventuretocode keep me posted on the isInitialLoad issue please^ Leaving this issue open

adventuretocode commented 3 weeks ago

@kinngh Thank you for your help. However, I am facing an issue where the app is not redirecting properly. The URL it is getting stuck on is "trycloudflare.com/?hmac=45362f9ede8020f99b2".

Can you please assist with this?

Thank you.

kinngh commented 3 weeks ago

Need more info / logs / screen cast on what's happening

adventuretocode commented 3 weeks ago

@kinngh Thanks for the support on the issue. I can see the server side one Error then it redirect again. I think Due to this error API getting 400

shopify-node-express-mongodb-app-main/utils/shopify.js made log level 3

  logger: { level: isDev ? 1 : 3 }, //Error = 0,Warning = 1,Info = 2,Debug = 3

Sp auth error - Screenshot Screenshot from 2024-06-12 13-42-21

One more error SP auth - error -- creenshot

Screencast from 12-06-24 02:02:14 PM IST.webm

kinngh commented 3 weeks ago

@adventuretocode questions:

  1. Why do you have a 404 to /api/apps in the video?
  2. How do you get to the point where shop is undefined?
  3. I tried to delete sessions mid way to try and emulate a breakage - can't see it yet. Is your version of the app migrated from the previous version or did you make a new pull?
adventuretocode commented 3 weeks ago

@kinngh
Thank you for your hard work on this project. I appreciate any guidance you can provide.

1. 404 Error in /api/apps: In the video, -> there is a 404 error when accessing /api/apps. The page debug card shows one successful API call followed by a 404 error on the second attempt. 2. Undefined Shop Variable: How does the shop variable become undefined? -> server/middleware/isInitialLoad.js I added the log. please find the code. Screenshot from 2024-06-13 15-40-02

3. I tried to delete sessions mid way to try and emulate a breakage - can't see it yet. Is your version of the app migrated from the previous version or did you make a new pull? -> I did pull the latest version and ran the clean repo code but encountered a 400 error I am not able to find the what was the use case getting the 400 form the Shopify library Token validate failed .

kinngh commented 3 weeks ago
  1. Still not sure why it's a 404 - if it was a 403/405, it was understandable but a 404 is just weird.
  2. Ok so I wouldn't be worried about it as it's expected - which is why you have the if (shop && idToken) there.
  3. Hmm ok.

Some more questions:

  1. Is it happening frequently, or is it happening every now and then?
  2. Are you in dev mode when it's happening or it's happening in production too?

If it's only happening in dev mode, I wouldn't be too worried about it. There's a bunch of stuff like JWT validation that just breaks because of HMR and only happens in dev mode. If you can replicate the 400 error in production mode too, I'll spend more time debugging because so far, in any of our production apps, I haven't seen this happen. This could be a quirk of HMR or some other thing in dev mode and I would just ignore it, if possible^

adventuretocode commented 3 weeks ago

@kinngh Thanks again for the fast support updates.

4. Is it happening frequently, or is it happening every now and then? -> This happens only sometimes. If I start the app the next day, the error occurs occasionally. I tried adding more logs to pinpoint where it stops, but I still haven't found the issue. 5. Are you in dev mode when it's happening, or is it happening in production too? -> Sure, let me monitor it in production mode now.

adventuretocode commented 1 week ago

@kinngh

I encountered an issue while running the app in production mode. The build was successful using Vite with no errors during the build process. However, I am seeing a session token error from Shopify, which appears to be an old error from the Shopify library.

If you report this error, please include this id: 7b57a278-39f7-4276-aa64-32c520d94fbe-1719408957

Steps to Reproduce Run the app in production mode. Observe the session token error from Shopify.

Error Log

Shopify - New versions - authg error - Screenshot

Expected Behavior The app should run without encountering session token errors from Shopify.

![Uploading Shopify api - Error -- 400 Bad req -- Screenshot.png…]()

kinngh commented 1 week ago

Got it - I'm out attending Editions.dev at the moment, let me circle back around first week of July around this^