App rejected due to redirecting to a different page when attempting to install your app

I have created a Shopify public app using node with Shopify CLI, So after i have submitted the app for the reviewing in the Shopify app store.

So they rejected the app mentioning the app is not directed to the scope page when we install the app ( in Incognito ) window in normal browser their is not mush issue.

The issue that point out buy the shopify

This was not initially when i submitted the app earlier.

server.js

import "@babel/polyfill";
import dotenv from "dotenv";
import "isomorphic-fetch";
import createShopifyAuth, { verifyRequest } from "@shopify/koa-shopify-auth";
import Shopify, { ApiVersion } from "@shopify/shopify-api";
import Koa from "koa";
import next from "next";
import Router from "koa-router";

dotenv.config();
const port = parseInt(process.env.PORT, 10) || 8081;
const dev = process.env.NODE_ENV !== "production";
const app = next({
  dev,
});
const handle = app.getRequestHandler();

Shopify.Context.initialize({
  API_KEY: process.env.SHOPIFY_API_KEY,
  API_SECRET_KEY: process.env.SHOPIFY_API_SECRET,
  SCOPES: process.env.SCOPES.split(","),
  HOST_NAME: process.env.HOST.replace(/https:\/\/|\/$/g, ""),
  API_VERSION: ApiVersion.October20,
  IS_EMBEDDED_APP: true,
  // This should be replaced with your preferred storage strategy
  SESSION_STORAGE: new Shopify.Session.MemorySessionStorage(),
});

// Storing the currently active shops in memory will force them to re-login when your server restarts. You should
// persist this object in your app.
const ACTIVE_SHOPIFY_SHOPS = {};

app.prepare().then(async () => {
  const server = new Koa();
  const router = new Router();
  server.keys = [Shopify.Context.API_SECRET_KEY];
  server.use(
    createShopifyAuth({
      async afterAuth(ctx) {
        // Access token and shop available in ctx.state.shopify
        const { shop, accessToken, scope } = ctx.state.shopify;
        const host = ctx.query.host;
        ACTIVE_SHOPIFY_SHOPS[shop] = scope;

        const response = await Shopify.Webhooks.Registry.register({
          shop,
          accessToken,
          path: "/webhooks",
          topic: "APP_UNINSTALLED",
          webhookHandler: async (topic, shop, body) =>
            delete ACTIVE_SHOPIFY_SHOPS[shop],
        });

        if (!response.success) {
          console.log(
            `Failed to register APP_UNINSTALLED webhook: ${response.result}`
          );
        }

        // Redirect to app with shop parameter upon auth
        ctx.redirect(`/?shop=${shop}&host=${host}`);
      },
    })
  );

  const handleRequest = async (ctx) => {
    await handle(ctx.req, ctx.res);
    ctx.respond = false;
    ctx.res.statusCode = 200;
  };

  router.post("/webhooks", async (ctx) => {
    try {
      await Shopify.Webhooks.Registry.process(ctx.req, ctx.res);
      console.log(`Webhook processed, returned status code 200`);
    } catch (error) {
      console.log(`Failed to process webhook: ${error}`);
    }
  });

  router.post(
    "/graphql",
    verifyRequest({ returnHeader: true }),
    async (ctx, next) => {
      await Shopify.Utils.graphqlProxy(ctx.req, ctx.res);
    }
  );

  router.get("(/_next/static/.*)", handleRequest); // Static content is clear
  router.get("/_next/webpack-hmr", handleRequest); // Webpack content is clear
  router.get("(.*)", async (ctx) => {
    const shop = ctx.query.shop;

    // This shop hasn't been seen yet, go through OAuth to create a session
    if (ACTIVE_SHOPIFY_SHOPS[shop] === undefined) {
      ctx.redirect(`/auth?shop=${shop}`);
    } else {
      await handleRequest(ctx);
    }
  });

  server.use(router.allowedMethods());
  server.use(router.routes());
  server.listen(port, () => {
    console.log(`> Ready on http://localhost:${port}`);
  });
});

Can you guys help to to over come this issue and cross the review barrier.

You would think that using the CLI would create a “Best-Practice” boilerplate, however, shopify is constantly changing the requirements for apps and making it harder to get approved. I think the problem is this line of code

ctx.redirect(`/auth?shop=${shop}`);

If I understand this correctly you are performing a 302 redirect with that line of code to the /auth route prior to redirecting to the Shopify authorize url

https://{shops myshopify domain}/admin/oauth/authorize/

That might be your problem.

Cheers

Gary

Hi @garyrgilbert Thanks for the replay

I make the changes in the code as you mentioned and updated it and after that also the issue is still there.

When i run that on the normal browser it runs fine..! but the issue occurs only when i open the app from the partners dashboard.

changes that i made.

if (ACTIVE_SHOPIFY_SHOPS[shop] === undefined) {
      ctx.redirect(`https://${shop}/admin/oauth/authorize/`);
    } else {
      await handleRequest(ctx);
    }

in incognito it shows like this

only when i click on the shop it will redirect to the oAuth page of the app.

The Shopify saying that they should need directly redirected to the oAuth page on the installing process.

But in Incognito we need to verify the shop what is a best solution for this.

Thanks

Hi,

The merchant will always open your app from within the Shopify admin, whether your app is an embedded app or not. That means that when you are in incognito mode you should first log into your shopify partner account in incognito mode, then install the app on the developer shop. Once you do that it should automatically redirect to the authorize url (with the correct url parameters). Take a look at this documentation to correctly create the authorize url with the correct redirect url.

Unfortunately, I never used that github repository so I can’t say how good it is or if its really production ready.

Keep your network tab open to see your traffic, something is going on which shouldn’t, which is obvious, but I can’t tell from here whats wrong. Sorry I couldn’t be more help.

Cheers

Sorry I can’t be more help

Hi @garyrgilbert

Thanks for your feedback..!

I understand the way that you suggested regarding the working of the app, But the issue that i mentioned is regarding the initial installation issue that mentioned by the Shopify review team.

The app is redirected to the page that i mentioned above when they try to install the app.

The issue that pointe out by the review team is that occur during the installation process of the app from the partner dashboard.

so in incognito it will ask to choose the account to continue and they are saying that after we click on the installation we must directly redirect to the oAuth page of the Shopify.

Is this the behaviour or any way to overcome the issue and complete the review process.

Thanks.