1

The goal is to display custom customer data inside /account securely. The user will need to login in Shopify store to access the route.

The data is tied to the Customer's email address in the server. So I'll do GET request with email address in the request URL.

In the /account liquid template I'm using Vue component. It will handle the request to a NodeJS API (I'm using feathers/express).

So far I read about App Proxy and App Bridge, but I don't know how those will fit here.

The main problem:

How do I secure the API to make sure only the logged in Shopify customer can get their own data inside the store? How do I verify the user and making sure the API only accessible via the store?

Note: I'm really new to Shopify. Please explain with more details. Thanks.

Laurensius Adi
  • 252
  • 3
  • 19

2 Answers2

3
  1. Create an app using the Shopify CLI tool, use command shopify node create to generate Node JS one.
  2. The generated app includes auth/callback that's needed for the app to be install-able on a Shopify store. Using this CLI, it also do the initial setup on Partner Dashboard.
  3. We can start the Node app using shopify node serve that'll start ngrok server, and updates the app's URL in App Setup. Then you'll need to setup App Proxy by copying the URL and put it inside App Setup.
  4. By using App Proxy, Shopify will "reroute" the call via Shopify backend with an added signature to your app/server, so we know the call is secure and is the correct one.
  5. Then we can verify the signature in URL query that comes from Shopify. Here's the code from Ruby rewritten in JS. I'm using it as a hook in my Feathers JS service.
const { NotAuthenticated } = require('@feathersjs/errors');
const crypto = require('crypto');
const safeCompare = require('safe-compare');

module.exports = () => {
  return async context => {
    const { query } = context.params;
    const signature = query.signature;
    delete query.signature;

    let sortedParams = '';
    for (const [key, value] of Object.entries(query).sort()) {
      sortedParams += `${key}=${value}`;
    }

    const calculatedSignature = crypto
      .createHmac('sha256', process.env.SHOPIFY_API_SECRET)
      .update(sortedParams, 'utf-8')
      .digest('hex');
  
    if (!safeCompare(calculatedSignature, signature)) {
      throw new NotAuthenticated();
    }

    return context;
  };
};
Laurensius Adi
  • 252
  • 3
  • 19
0

It is easy. The terminology is a little odd but here is all you need to know.

  1. Setup an App Proxy in your App

That will let you know the incoming call is secure and from Shopify. The call can include two key parameters, namely the email and customer ID.

  1. get the interesting data, and return JSON

So you have an email, and an ID. Now you can securely get the customer account data that matters, and return it in JSON to your component on the front-end.

That is it. Nothing more to it. Have fun.

David Lazar
  • 10,865
  • 3
  • 25
  • 38
  • How does the verification work in server so I know the request is right? What does the app need to implement so it can accept "Install App" request? – Laurensius Adi Sep 03 '21 at 04:39
  • 1
    I only found tutorials on building app for Shopify Admin, not the customer facing app/server that I need. Can you show me a tutorial or code? – Laurensius Adi Sep 03 '21 at 06:24
  • Shopify offers a complete, full-suite of documentation on how to correctly build Apps. Refer to Shopify documentation to explain all you need to know. They even offer you NodeJS App builders to get you started. – David Lazar Sep 03 '21 at 13:52
  • The only problem now signature calculation code is in Ruby, I'm using Node JS. https://shopify.dev/apps/online-store/app-proxies#calculate-a-digital-signature – Laurensius Adi Sep 03 '21 at 17:28
  • Scripting is Scripting. If you can understand Javascript, then you can certainly understand Ruby. It is a recipe. The exact same command in JS do with the Ruby does. There is little difference. Try and abstract it. As well, the Shopify Ruby NodeJS App has all the code you need in it to deal with signature calculations. – David Lazar Sep 03 '21 at 17:46
  • It would be more helpful if you can point out the Node version example link. But thanks for the direction! – Laurensius Adi Sep 04 '21 at 07:56
  • 1
    @LaurensiusAdi I think you need to check theme app extensions for this. I am not sure how to bring all these together though. Still working on this. – iRestMyCaseYourHonor Dec 30 '21 at 12:15
  • It is true, I use Theme App Extensions when the customer is using online store 2.0 formatting for their theme. It works great for the most part. – David Lazar Dec 30 '21 at 15:12