1
votes

I've developed a couple of Shopify custom apps for people using node.js, and it's been a lot of trial-and-error honestly. That trial and error have led me to the following code:

/* GET home page. */
router.get('/', adminMiddleware, function (req, res, next) {
    const shop = req.query.shop;

    if (req.query.session) {
        // if we're here, that means the app was clicked on in the shopify admin panel
        return res.send({hello: 'world'});
    }

    if (shop) {
        // if we're here, that means this is install initialization
        const state = nonce();
        const redirectUri = forwardingAddress + '/shopify/callback';
        const installUrl = 'https://' + shop +
            '/admin/oauth/authorize?client_id=' + apiKey +
            '&scope=' + scopes +
            '&state=' + state +
            '&redirect_uri=' + redirectUri;

        res.cookie('state', state);
        res.redirect(installUrl);
    } else {
        return res.status(400).send('Missing shop parameter. Please add ?shop=your-development-shop.myshopify.com to your request');
    }
});

So, according to my trial and error, which I'm not confident about at all, I will end up at the root of my Shopify routes (as defined in the App URL setting on the Shopify partner dashboard) under 2 scenarios:

  1. when someone is installing the app, in which case I will expect a shop in the query parameters, or

  2. when someone clicks on my app inside their Admin Panel of a Shopify store, in which case there will be a req.query.session variable set, and I can respond I guess with some html+css if I want to (the example just shows a simple JSON response).

But... is that right? Are those the two scenarios Shopify will be using my root route? And is checking for req.query.shop or req.query.session the proper way to distinguish between those two circumstances? I'm not sure I'm dealing with this stuff properly.

1

1 Answers

0
votes

I'm not a an expert on the matter, but I have a few apps behind my back and I'm using nodejs as well so if what I know can help you, be my guest.

First my recommendation is to use the shopify-cli setup here https://shopify.github.io/shopify-app-cli/ it provides a Shopify App starterkit written on NextJS and Node(it's using KOA, it has a GraphQL included and some other predone things for you), that has all the auth middleware done for you. I was using a custom express but because the support for an important auth express package was dropped I switched to koa and after that to their setup. So yep my recommendation is to go with their setup.

As to your question, it really depends what is configured to be on your route.

There a few different request that shopify can send depending on what type is your app (custom or public) and if you have a proxy.

Here are all the possible requests that you can receive (or the ones I have worked with):

  • initial install - this request includes a few end-points, one for the URL generation, one for the callback validation
  • enter app - I'm not sure if this request can exclude the session, the current setup has a session configured, so I assume it may be possible to not include it
  • proxy request - if you have setup a proxy in your app dashboard and this is the end-route
  • webhook request - if you register a webhook and this is your end-points
  • GDPR webhooks - these are configured from the dashboard and are required for Public apps (but they work in similar way like the webhooks)

It really depends how your app is configured, you can have all 5 requests on the same route (which is a bad idea) or a single one if you don't need even a dashboard for the app.

Have in mind that you can have the installation and home in separate routes if you don't want to deal with this, just set the initial "home" page from the app dashboard to be a different one.

If you are working with Koa I think that this package will help your flow much more https://www.npmjs.com/package/@shopify/koa-shopify-auth since it's supported by Shopify.

In addition I don't see you handling the shop query param, which may result in XSS attacks on your side, please consider sanitizing it before outputting it in the installation URL.

So at the end consider using a startkit here since it will be easier to provide support for public apps afterwards, since they have strict review process for their public apps and it's easier to have a reference to their community forum when there is an issue you need to fix or feature you need to add.