Development
October 16, 2021

Shopify App Authentication  - There's a Better Way

This is part two in a series of articles documenting the process of building our first Shopify app. Click here for part one.

The Annoying Part of Shopify App Development

If you’ve built a Shopify App before, you know all too well the time and effort needed to handle all of the authentication and installation procedures required for each app you want to create. It is a vital, but cumbersome process we all must endure before we get to the fun parts of actually building our app.

The good news? We can get this part of the app out of the way before we even know what app we’re building, and once we’re done, we’ll have a template we can reuse in the future when building our next app!

However, making changes to any part of this process will be difficult as it will need to happen in two places, and then three, then four, and the workload would keep scaling as our app portfolio grows.

This is where we decided to branch off a little at Shopside, and consider if there was an even better way to do this, while still keeping aligned with our core values.

Note to self: Yes, there is always a better way.

Sessions, Tokens and OAuth, Oh My!

We dared to dream, and thought about our ideal method for handling Shopify’s installation and authentication requirements, which is not a small list by any means. It includes handling OAuth installation, session tokens, HMAC signatures, managing subscriptions/charges and more.

Our ideal solution, was a single service which could be used by an unlimited number of apps, and would handle all installation steps, as well as any verification/authentication requests that needed to happen and interact with our backend database.

Basically any process that would be repeated in every app, should be handled by this service if possible, so it only exists in one place, and the functionality can be abstracted to an external service, reducing the size and complexity of our apps moving forward.

We did a little research around the requirements and realised that we could indeed cover everything we need with an external service. We decided on our technology stack, and created the first version of our Shopify Authentication Service!

A Scalable, Reusable Authentication Service

It is important that our Authentication Service can handle thousands of requests without breaking down, as every time a store loads our app, an authentication request will need to be sent to verify they have the app installed with an active subscription. This may also need to happen on every request on the front-end store (depending on the app specifics), so we need to be prepared for massive amounts of traffic.

Serverless to the rescue!

For this reason, and because we were familiar with the technology, we decided to build the service as a Serverless NodeJS application, which allows us to setup and manage a stack of Lambda functions within AWS, and attach them to public URLs via API Gateway.

Each Lambda function runs as a separate serverless function, and will automatically scale the number of functions running simultaneously as demand increases or decreases. Perfect!

Using Serverless means that all of our AWS resources are managed via a .yml config file, saving us from the complicated UI that is AWS. Creating and deploying our service is a breeze:

Database? Yes please.

We decided to use Supabase to host our PostgreSQL database, and to separate each app into their own database project. Although they would all share an identical shop table (to track installs and store access tokens etc.), we decided it would be better to keep each app as separate as possible.

Shopify OAuth Flow

Before we take a look at the Authentication Service, let’s first understand how the OAuth process works and what steps we need our service to perform.

Here is a helpful diagram outlining the flow of events:

A flowchart diagram showing the Shopify OAuth process.
Image taken from Shopify Dev Docs

And this is the explanation Shopify give in their documentation:

  1. The merchant makes a request to install the app.
  2. The app redirects to Shopify to load the OAuth grant screen and requests the required scopes.
  3. Shopify displays a prompt to the merchant to give authorization to the app, and prompts the merchant to log in if required.
  4. The merchant consents to the scopes and is redirected to the redirect_uri.
  5. The app makes an access token request to Shopify including the client_id, client_secret, and code.
  6. Shopify returns the access token and requested scopes.
  7. The app uses the access token to make requests to the Shopify API.
  8. Shopify returns the requested data.

Their documentation has a lot more in-depth information on each step if you’re interested in learning more. For now, let’s assume we understand the process perfectly.

How Does The Service Work? No, really.

Now that we have all the pieces in place, let’s go through the structure and functionality so we can understand how everything connects. Time to get technical 😎

/serverless.yml

This is the current configuration for the service, which implements three lambda functions, auth , verify and confirm:

Let’s dive a little deeper and see what each handler is doing:

/handlers/auth.js

This handler function is quite simple, and serves as the entry point for our app. It uses a few basic classes we wrote for basic database and Shopify API interaction, as well as some config handling and lambda response normalising.

It will ensure:

  1. The app is installed in the database and has a valid accessToken
  2. The subscription status is ACTIVE
  3. If these two conditions are true, it will redirect the user to the app itself, and if not, it will redirect to the OAuth installation URL! Easy peasy!

/handlers/verify.js

After redirecting to the OAuth installation URL, the user will have to review the permission scopes being requested and authorize the installation of the app.

A screenshot of the Shopify OAuth installation page.
The OAuth installation prompt. Image taken from Shopify Dev Docs

Once this is done, the user will be sent back to our Auth Service to handle the actual installation. This is where our second handler function comes in, and does most of the work!

There’s a decent amount of code here so let’s look at each step! We:

  1. Use the code parameter provided by Shopify to fetch an accessToken using Shopify’s API. This is a permanent access token that we will use for as long as the user has the app installed! We store this in our database for all future API requests.
  2. Fetch shop data from the Shopify API (this gives us some basic information like name, email, domain, so we know which installation is for which store, and gives us a contact if we need to offer support).
  3. Check there is a host parameter provided by Shopify when it redirects back to us (as we need to store that for future use too!).
  4. Save shop record to database.
  5. Register the webhooks we want to listen to (app/uninstalled and shop/update ).
  6. Create the recurring subscription Charge via the Shopify API (using the access token we stored earlier).
  7. Update the shop record with the new subscription data (this will be a PENDING charge until the user confirms the payment on the next step).
  8. If all is successful, we redirect to the confirmationUrl provided by Shopify when we created the Charge.

Phew! A lot of steps, but nothing we can’t handler! Now the user will be faced with a confirmation screen where they can approve the subscription and enter their payment details.

Once they have confirmed the payment, there is one final redirect back to our third handler.

/handlers/confirm.js

  1. This handler has the simple job of confirming the Charge was paid, by re-fetching the subscription data from the Shopify API. The subscription status should now be ACTIVE instead of PENDING and we update that to reflect in the database.
  2. If everything checks out, we redirect the user to the app itself and relinquish all control!

And that’s all that this service needs to worry about! High five! 🙏

Awesome! …Now What?

Now that all the annoying parts are out of the way, we have a fully reusable and scalable Authentication Service for our Shopify Apps!

It’s time to start planning and building the app itself!

…Any ideas?

Part three of this series is now available, covering the ideation of our app and how we defined its scope.

Recent Articles