Shopify App

Original link: https://blog.othree.net/log/2022/08/18/shopify-app/

When I developed the Shopify App before, it took a long time to get his installation done, so I decided to record the pits I stepped on. This article is suitable for those who have started to develop the Shopify App. Some basic knowledge of the Shopify App will not be mentioned. Now, let’s define the following terms clearly:

  • App refers to the Shopify third-party app developed by us
  • Merchant refers to merchants who sell on Shopify
  • Installing an app refers to merchants installing a third-party app developed by us on their Shopify store

First of all, part of the reason I have stepped on a lot of pits is because I use NodeJS as the server-side language, and I choose Express, but the official Express architecture app example has stopped maintenance, and replaced it with the Koa version of @shopify/koa -shopify-auth is only responsible for the verification-related middleware, but in fact, I just need the auth-related part, but the difference is not the Express version, I can also study and see how to implement it myself.

Taking a look around, I found that there is actually another @shopify/shopify-api that is responsible for processing logic related to Shopify at the bottom layer, so theoretically I can also use it with Express, but there is a pit first here, an example of initialization It looks like this:

 Shopify.Context.initialize({ API_KEY: process.env.SHOPIFY_API_KEY, API_SECRET_KEY: process.env.SHOPIFY_API_SECRET, SCOPES: process.env.SHOPIFY_APP_SCOPES, HOST_NAME: process.env.SHOPIFY_APP_URL.replace(/^https:\/\//, ''), API_VERSION: ApiVersion.October20, IS_EMBEDDED_APP: true, // More information at https://github.com/Shopify/shopify-node-api/blob/main/docs/issues.md#notes-on-session-handling SESSION_STORAGE: new Shopify.Session.MemorySessionStorage(), });

It can be seen that there is a SESSION_STORAGE at the end, which is an adapter that handles the storage method of the access token obtained by our app when the merchant installs the app. However, the official example is to use Memory Storage. This adapter only exists in memory. In fact, It is only suitable for development. As long as your server is restarted, all merchants will have to reinstall your app. Otherwise, your app will not have an access token to communicate with Shopify. In fact, you should refer to the document Custom Session Storage . , select the applicable adapter, I wrote a version of GCP FireStore with reference to the example, of course, there is no special mention, because it is to store the access token, it is best to consider the encryption of the DB.

The second pit is how to do Shopify’s authentication and identification. First, how to verify that the request is credible. The design of the Shopify API depends on the hmac in the query string parameter, which is based on the secret of your App. Then, the pit here is that there is a validateHmac in the official suite @shopify/shopify-api that can be used, but its calculation is actually incorrect. It is calculated by using the query string parameter that only takes part of the whitelist. , the results will be different from those given by Shopify, so I use the example given by Muhammad Kamal in the GitHub issue discussion thread.

The third pit is the route used to install the App. The design of Shopify is a bit special. All the initial requests (whether it is the first installation or the setting screen of entering the App from the Shopify background) are very close, so You have to decide what to do based on various situations. Here are all possible situations:

  • First time to install
  • After installation, go to the setting screen
  • Once installed, but need to re-authorize, possible reasons:
    • The permissions required by the app have changed
    • The access token on the App side is invalid
  • Shopify thinks it has been installed, but there is no information on the app side

In addition to the change of the required permissions, it is actually a permutation and combination. The Shopify side thinks it has been installed, and the App side thinks it has been installed. There are four possibilities by two times two, but there are actually only three processing methods: initial installation. , re-authorization, installation of no problem happy path (happy path) organized into a program process is probably:

  1. Verify hmac, if not, you can directly return 400
  2. Determine if the shop is in the database
  3. 2 Verify the access token in the database, if any
  4. 3 If the verification is passed, the status is happy path. Shopify thinks that the app is installed, and there is no problem with the app-side check. I name this status valid
  5. 3 If the verification fails, determine whether there is a query string parameter of session
  6. 5 If there is, the status is that the access token on the app side cannot be used, and the reauthorization process needs to be performed. I named this status invalid
  7. 5 If not, it is the process of the first installation, I named this state not_found
  8. Finally, if there is no 2, it is also the authorization process of the initial installation, which can also be called not_found .

Then, if the permissions required by the app change, in theory, every time you come in and verify the access token, you can go to the API to ask the access scope of the current token , but I haven’t done this part, because I don’t have the relevant requirements yet.

The header X-Shopify-API-Request-Failure-Reauthorize may be found on the Internet, but this is not a response from Shopify API, but a mechanism designed in Shopify’s app-template . In their app template, the server is forwarding When an Ajax API request is made, if an error is received from the Shopify side, this header is added and returned to the front end of the app. After the front end of the app receives this header, it can enter the re-authorization process through the Shopify app-bridge.

Speaking of this, some people may be curious, why do you need to separate the two processes of app installation and reauthorization? In fact, this can be regarded as the fourth pit, and it is also related to the user experience. The situation is that Shopify thinks that when it is installed for the first time, it directly enters the OAuth process, so the top window of the browser is directly redirected to the auth page, but If it needs to be re-authorized, the Shopify side thinks it has been installed, but the app side thinks it needs to re-run OAuth, and at this time, the browser window connected to the app server is in the iframe in the backend of the Shopify store. The OAuth authorization cannot be completed correctly in the iframe, so you need to use Shopify’s current set of tools called app-bridge to help, so that the OAuth process starts from the top window, so you need to return to an HTML page, introduce the script of app-bridge , and then execute The following JS:

 const AppBridge = window['app-bridge']; const createApp = AppBridge.default; const Redirect = AppBridge.actions.Redirect; const app = createApp({ apiKey: '', host: '', }); const redirect = Redirect.create(app); redirect.dispatch( Redirect.Action.REMOTE, '/url/to/your/auth?shop=' );

Of course, remember to replace what should be replaced, and then you can see the correct OAuth authorization process from the top window.

The last pit is actually the problem that the status of Shopify and the app side will be inconsistent after the Merchant uninstalls the app. The Shopify side thinks it is not installed, but the app side thinks it is installed, although the program flow I designed above can already handle this situation ( Verifying the access token will fail, and then there will be no session parameters, so it will enter the initial installation), but this situation should be avoided if it can be avoided, and the solution is to support webhook, the things to do are:

  1. After the installation is complete, go to subscribe to the webhook event APP_UNINSTALLED
  2. Then after receiving this event, delete the corresponding data in the database

Here I am using tools provided by @shopify/shopify-api like
Shopify.Webhooks.Registry.register and Shopify.Utils.deleteOfflineSession , if you really want to do it yourself, it’s not impossible, but I remember that Shopify’s webhook is a bit cumbersome to deal with.

These details are that the official documents have not been written clearly. Although there are already a lot of official documents and efforts have been made to sort them out, in fact, there are still many problems if you want to receive them yourself, so I wrote an article to record them, although I don’t know if they will There are other people in the Chinese circle who need to make their own Shopify app. It is relatively simple to use their app template directly.

This article is reprinted from: https://blog.othree.net/log/2022/08/18/shopify-app/
This site is for inclusion only, and the copyright belongs to the original author.

Leave a Comment