Blog Details

It's no secret that the more you know your customer, the more easily you will be able to create personalized experiences, build brand loyalty, and increase conversions. One of the best ways to gather customer information to better meet these goals is through account registration and logins. However, this can become a friction point in a customer journey if not done right.

One of the best solutions to overcoming this barrier is by using a central authentication source like Auth0 that will allow your customers to have one username and password that works across all your properties. Not only will this approach reduce "login fatigue" on the customer side, but also, your team can get a better single, unified view of your customers across brands, partners, and digital touch points.

Recently, a BlueBolt client started an organization-wide implementation of Auth0 as their authentication service across all their customer-facing properties. Part of this rollout includes replacing the native Shopify logins with an Auth0 authentication user flow. In this blog, I will expand upon the primary steps involved in this process, which are:

  1. Enable Multipass on the Shopify account 
  2. Create an Auth0 Application  
  3. Add an Auth0 rule to create Multipass token and redirect user 
  4. Update Shopify Theme with Auth0 Links 
  5. Optional: Capture First & Last Name During Signup

Prerequisites

Before we get started, you’ll need to make sure you’re ready to go with the following requirements. First, Shopify requires a Shopify Plus storefront. If you’re a Shopify Partner, you can create development stores to test out any functionality you need to implement on a Plus store.

Second, an Auth0 account is also required. Auth0’s free tier includes everything necessary, but even if it didn’t, a newly created instance includes all paid features for a few weeks to get you started.

1. Enable Multipass on Shopify account

In order to enable Multipass, log into the Shopify store, go to the Settings page and click into the Checkout window. Make sure customer accounts are set to either optional or required.


This is an important step in ensuring Shopify can verify that a Multipass is legitimate; the encryption routine can now create a cipher that Shopify will be able to decrypt. If you ever suspect that your Multipass key has been compromised, then disable and re-enable Multipass. This will generate a new secret key which you will need to copy into Auth0.

2. Create an Auth0 Application

Within the Auth0 dashboard, go to Applications, click Create Application, give it a name like “Shopify Store” (it’s important to note that the name of the application is publicly visible!) . Then choose the Regular Web Application.


Skip the Quick Start and go to Settings.

For the following sections, you need to substitute {shopify-domain} with the domain of your particular store (ex: sample-store.myshopify.com)

  • Allowed Callback URLshttps://{shopify-domain}/account
  • Application Login URIhttps://{shopify-domain}/account/login
  • Allowed Logout URLshttps://{shopify-domain}/account/logout

Expand the Advanced Settings section and add these two key/value pairs under Application Metadata:

  • Key: shopify_domain; Value: {shopify-domain}
  • Key: shopify_multipass_secret; Value {multipass-secret}


3. Add Auth0 rule to create Multipass token and redirect user

Now that we have a landing point for the Shopify store to send users to, we need to be able to pass the authenticated user back to the Shopify store. This is where Multipass comes into play.


Start by creating a new Rule in Auth0, using the Empty rule template, and give it a descriptive name (like: “Shopify Multipass”), and paste in the following code:

1

function (user, context, callback) {

2

if (context.clientMetadata && context.clientMetadata.shopify_domain && context.clientMetadata.shopify_multipass_secret)

3

{

4

const RULE_NAME = 'shopify-multipasstoken';

5

const CLIENTNAME = context.clientName;

6

console.log(`${RULE_NAME} started by ${CLIENTNAME}`);

7

8

const now = (new Date()).toISOString();

9

let shopifyToken = {

10

email: user.email,

11

created_at: now,

12

identifier: user.user_id,

13

remote_ip: context.request.ip

14

};

15

if (context.request && context.request.query && context.requ.query.return_to){

16

shopifyToken.return_to = context.request.query.return_to;

17

}

18


19

if (context.user_metadata)

20

{

21

shopifyToken.first_name = user.user_metadata.given_name;

22

shopifyToken.last_name= user.user_metadata.family_name;

23

}

24

25

const hash = crypto.createHash("sha256").update(context.clientMetadata.shopify_multipass_secret).digest();

26

const encryptionKey = hash.slice(0, 16);

27

const signingKey = hash.slice(16, 32);

28

29

const iv = crypto.randomBytes(16);

30

const cipher = crypto.createCipheriv('aes-128-cbc', encryptionKey, iv);

31

const cipherText = Buffer.concat([iv, cipher.update(JSON.stringify(shopifyToken), 'utf8'), cipher.final()]);

32

33

const signed = crypto.createHmac("SHA256", signingKey).update(cipherText).digest();

34

35

const token = Buffer.concat([cipherText, signed]).toString('base64');

36

const urlToken = token.replace(/\+/g, '-').replace(/\//g, '_');

37

38

context.redirect = {

39

url: `https://${context.clientMetadata.shopify_domain}/account/login/multipass/${urlToken}`

40

};

41

   }

42

   return callback(null, user, context);

43

}

view rawauth0-rule-shopify-multipass.js hosted with by GitHub

  • Line 2: since Auth0 runs all rules for all authentications, we want to restrict this to just when the Auth0 Application has declared the shopify_domain and shopify_multipass_seceret metadata.
  • Line 4-6: Some minor logging, just to verify that the rule is being run.
  • Line 8-14: Shopify requires at least the email and created_at data points. For added information, we are also passing an identifier (in case multiple Auth0 accounts have the same email address) and remote_ip to ensure that this Multipass request can only be used by the same computer that sent the initial login request.
  • Line 15-17: If there is a return_to value in the query string, then add this to the Shopify token.
  • Line 19-23: In another post of mine concerning TalentLMS/Auth0, I describe how to grab first/last name when signing up a user. If that is in place, this will also add those data points to the Shopify account.
  • Line 25-36: These lines that do the actual encryption were taken from a repository that I found on GitHub, so thanks go to Cory Smith from Calgary, AB for this one.
  • Line 38-40: This sets the destination for the authenticated user.

Once this rule runs, the user will be redirected back to the Shopify store. This is important, because if there are any Auth0 rules after this one, they will be completely skipped.

4. Update Shopify Theme with Auth0 Links

For this example, we are just going to add a login link for Auth0. If you want to completely replace the Shopify Login process with Auth0, then instead of presenting the user with a login page, you can redirect the user directly to Auth0. As a proof-of-concept, though, this will require the user to manually click the link.

Start by editing the current theme (or whatever theme you want to use to test this out).


Within the Login page, typically under Templates you’ll find the customers/login.liquid file. Find a good place to add the link; you can see below that I put it next to the “Create account” link.

<a href="{{ settings.auth0_login_url }}">Log in with Auth0</a>



You may also want to put a link on the registration page, located in the customers/register.liquid template. If you are completely replacing Shopify logins with Auth0, then this will be another page where you will redirect the user straight to Auth0 instead of requiring them to click on a specific link.

Next up is to replace the logout link with the Auth0 logout. There is a logout link on the account page, found in customers/account.liquid. If your theme has a logout link anywhere else, that will also need to be replaced with the following:

<a href="{{ settings.auth0_logout_url }}">{{ 'layout.customer.log_out' | t }}</a>


Finally, we need to configure the theme settings to allow a user to paste the login and logout URLs. Open the settings_schema.json file and paste the following snippet to the end of the array. This will provide an admin user the ability to key in the URL value without having to modify the theme templates directly.


This snippet creates a new settings section called “Auth0 Config” and will add the two inputs that we need. Note, that the id property matches the name of the properties we used above for the login and logout links.

{

  "name": "Auth0 Config",

  "settings": [

    {

      "type": "text",

      "id": "auth0_login_url",

      "label": "Auth0 Login Url",

      "info": "The full Auth0 URL to redirect the customer to for login."

    },

    {

      "type": "text",

      "id": "auth0_logout_url",

      "label": "Auth0 Logout Url",

      "info": "The full Auth0 URL to redirect the customer to for logout."

    }

  ]

}

Add URL Values

To put the values for the Auth0 URLs, you can either directly edit the settings_data.json file or you can use the Shopify admin UI. I prefer the UI, because then Shopify handles escaping any necessary characters.

Let’s first build the login URL. Go back to Auth0 and copy the Client ID for your application (it’s the one created in step 2).


  • auth0-instance: the URL for your Auth0 instance.
  • clientid: the value from Auth0
  • shopify-domain: the domain you want the user sent back to. This must match the Allowed Callback URLs initially specified.
  • return-to-path: this can either be set as a hardcoded value (like “account”) or it can be dynamically replaced with JavaScript on the page. This is helpful if you want to override the login on the Cart page.

https://{auth0-instance}.auth0.com/authorize?response_type=code&client_id={clientid}&return_to=https://{shopify-domain}/{return-to-path}&scope=SCOPE&state=STATE

The logout URL looks very similar:

  • auth0-instance: the URL for your Auth0 instance.
  • clientid: the value from Auth0
  • shopify-domain: the domain you want the user sent back to. This must match the Allowed Logout URLs initially specified.

https://{auth0-instance}.auth0.com/v2/logout?response_type=code&client_id={clientid}&returnTo=https://{shopify-domain}/account/logout

Now you can go back to the Themes page and click the Customize button and switch to the Theme settings, then expand the Auth0 Config section, and paste the URLs from above.


5. Optional: Capture First & Last Name During Signup

The final step is to customize the Sign Up page to require the user to enter values for First and Last name. The simplest way that I have found to do this is to customize the login page in Auth0. Under Universal Login, click on the Login tab, toggle the “Customer Login Page” and select the “Lock” Default Template. This uses the Auth0Lock and for our purposes, we will be utilizing the additionalSignUpFields array configuration option. Add the following JSON snippet to the code block:

additionalSignUpFields:[{

  name: "given_name",

  placeholder: "Enter your First Name"

},

{

  name:"family_name",

  placeholder:"Enter your Last Name"

}],


And it should look something like this:


Click Save Changes and that should be it! Go back to Shopify’s login page to test it out. To make sure it really works, log yourself out of Shopify, and when logging back in, click the Log in with Auth0 link you created earlier. You can go through the Sign Up workflow, which should require First name, Last name, Email, and Password.

In Production

Once you are ready to require all users to use Auth0 to login, the customers/login.liquid template can be completely replaced with a redirect to the auth0_login_url. All links to the login page can be replaced with direct links to the same setting. Also, all logout links need their URL to be replaced with the auth0_logout_url setting.

Conclusion

As mentioned in the beginning of this article, replacing native Shopify logins with Auth0 enables a centralized authentication service which can be combined with other third-party websites. By following the steps I’ve outlined above, you and your team can focus less on building your own authentication solution and more on delivering trusted and innovative digital experiences to your customers.


Note: The original version of this article was posted on Rovani in C#, a blog owned and written by BlueBolt Senior Solutions Architect, David Rovani.