Affinidi Login - Passwordless Authentication for Shopify

In this guide, learn how to integrate Affinidi Login on your Shopify store.

Affinidi Login can be integrated easily with any application that supports OIDC flow.

This integration guide provides step-by-step instructions to enable users to have a Passwordless Login experience into your Shopify Store using Affinidi Login as the Identity Provider.

This feature will auto-create users and update user attributes like first name, last name, address, etc. from Affinidi Login to your Shopify customer profile.

Assumptions

  1. You already have a development store created where you would configure Affinidi Login. If you need to create one then follow instructions here.

  2. Information presented here is recommended as a learning guide for non-production environments. We recommend to reach out to Affinidi team through Discord to assess and adjust the production readiness together for your specific store.

Before you begin

  1. Set up Affinidi Vault account. Follow the guide below if you haven’t set it up yet.
Set up Affinidi Vault

Set up an Affinidi Vault account using the Web Vault or install the Mobile Vault (for Android).

The same setup steps for Mobile Vault.

  1. Click on Get started if you are creating a new account, or click on Restore from Backup if you have an existing backup of your Affinidi Vault. Provide the Passphrase to secure your Affinidi Vault.

You have the option to enable Biometrics to unlock your Affinidi Vault easily instead of using Passphrase.

Affinidi Vault Setup
  1. Enter your email address to register with the Affinidi Vault. An OTP will be sent to this email for verification.
Affinidi Vault Passphrase
  1. Enter the OTP sent to the email you have provided for verification to complete the setup.
Affinidi Vault Email Verification

After successfully providing the OTP, you are redirected to the Affinidi Vault dashboard.

  1. Install the Affinidi CLI. Follow the guide below if it hasn’t been installed.
Set up Affinidi CLI
  1. Download and install NodeJS on your machine if you haven’t set it up yet.
  1. Install Affinidi CLI using Node Package Manager (npm).
npm install -g @affinidi/cli
  1. Verify that the installation is successful.
affinidi --version
  1. Choose a Social Login App that supports Custom Identity Provider (IdP) configuration.

    You can use third-party apps available on the Shopify App Store to enable OpenID Connect (OIDC) based Authentication flow on your Shopify store. This mechanism will allow customers to sign in or create accounts on your store using their verified credentials in Affinidi Vault. Visit the Shopify App Store and search for a social login app. Read reviews, check features, and choose an app that suits your needs.

Setup Instructions

Configure the Social Login App in your Shopify store

This guide provides step-by-step instructions with a popular option - miniOrange Single Sign OnSSO. The broad setup steps should be similar to any other apps you choose.

Many apps may provide a free trial period that you may consider as you make this choice.

The following steps assume you have experience with the miniOrange Single Sign on-SSO App.

Click on miniOrange Single Sign OnSSO app, then click the “Install” button.

Following are more detailed step-by-step instructions:

  1. Go to your Shopify Admin portal and select your store.

  2. Click on Settings menu under bottom left side menu bar.

shopify-admin-portal-home
  1. Select Apps and sales channels option and click on Shopify App Store.
shopify-app-store
  1. On Shopify App Store page, search for SSO and select miniOrange Single Sign On‑SSO App.
shopify-store-minorange-app
  1. Click on Install button, which will redirect to your store.
minorange-app-install-page
  1. Click on Install button to install the App in your store. This app requires access to create/read customers record.
miniorange-app-install-scopes
  1. Open the installed app by clicking on Apps menu on left side panel and select miniOrange.
miniorange-open-app
  1. Enable Login button, SSO Button Text & Styling:
  • Name: Affinidi Login

  • Width: 188px

  • Height: 48px

  • Background Color: R 29, G 88, B 252)

  • Attribute Mapping to your Shopify website as given below

    • Email: email
    • Customer Tags: sub
    • Firstname: given_name
    • Lastname: family_name
miniorange-setup-styling
  1. We need OAuth Callback URL where Affinidi Login enabled Authorization Server redirects the user to complete the authentication flow.
  • Click on SETUP IDP option under miniOrange App, which will take you to miniOrange App hosted environment.

  • Click on Add Identity Provider button, then click on OAuth 2.0 tab item and copy the Callback URL.

miniorange-oauth-callback

Create Login Configuration for Social Login App

  1. Go to  Affinidi Login under the Services section.

  2. Click on the Create Login Configuration and provide the required details.

  • Name as the Shopify App
  • Redirect URIs as the OAuth Callback URL copied from the previous step (e.g. https://store.xecurify.com/moas/broker/login/oauth/callback/23456)
  • Auth method as None to enable PKCE flow as a best practice
Create new Login Configuration
  1. Customise your Presentation Definition and ID Token Mapping by expanding the Additional Configuration section and clicking on the Create New button

  2. Copy the Presentation Definition below to request Email Address and Profile Information of the user. Paste it in PEX editor, then click on Continue button.

{
  "id": "vp_email_user_profile",
  "submission_requirements": [
    {
      "rule": "pick",
      "min": 1,
      "from": "A"
    }
  ],
  "input_descriptors": [
    {
      "id": "email_vc",
      "name": "Email VC",
      "purpose": "Check if VC data contains necessary fields",
      "group": [
        "A"
      ],
      "constraints": {
        "fields": [
          {
            "path": [
              "$.type"
            ],
            "purpose": "Check if VC type is correct",
            "filter": {
              "type": "array",
              "contains": {
                "type": "string",
                "pattern": "Email"
              }
            }
          },
          {
            "path": [
              "$.credentialSubject.email"
            ],
            "purpose": "Check if VC contains email field",
            "filter": {
              "type": "string"
            }
          },
          {
            "path": [
              "$.issuer"
            ],
            "purpose": "Check if VC Issuer is Trusted",
            "filter": {
              "type": "string",
              "pattern": "^did:key:zQ3shtMGCU89kb2RMknNZcYGUcHW8P6Cq3CoQyvoDs7Qqh33N"
            }
          }
        ]
      }
    },
    {
      "id": "givenname_vc",
      "name": "givenname VC",
      "purpose": "Check if VC data contains necessary fields",
      "group": [
        "A"
      ],
      "constraints": {
        "fields": [
          {
            "path": [
              "$.type"
            ],
            "purpose": "Check if VC type is correct",
            "filter": {
              "type": "array",
              "contains": {
                "type": "string",
                "pattern": "HITGivenName"
              }
            }
          },
          {
            "path": [
              "$.credentialSubject.givenName"
            ],
            "purpose": "given Name",
            "filter": {
              "type": "string"
            }
          }
        ]
      }
    },
    {
      "id": "familyName_vc",
      "name": "familyName VC",
      "purpose": "Check if VC data contains necessary fields",
      "group": [
        "A"
      ],
      "constraints": {
        "fields": [
          {
            "path": [
              "$.type"
            ],
            "purpose": "Check if VC type is correct",
            "filter": {
              "type": "array",
              "contains": {
                "type": "string",
                "pattern": "HITFamilyName"
              }
            }
          },
          {
            "path": [
              "$.credentialSubject.familyName"
            ],
            "purpose": "family Name",
            "filter": {
              "type": "string"
            }
          }
        ]
      }
    }
  ]
}
Modify Presentation Definition
  1. Copy the ID Token Mapping below. Paste it in ID token mapping editor and click on Done button. This ID Token format is based on the Presentation Definition we defined from previous step.
[
  {
    "sourceField": "$.credentialSubject.email",
    "idTokenClaim": "$.email",
    "inputDescriptorId": "email_vc"
  },
  {
    "sourceField": "$.credentialSubject.givenName",
    "idTokenClaim": "$.given_name",
    "inputDescriptorId": "givenname_vc"
  },
  {
    "sourceField": "$.credentialSubject.familyName",
    "idTokenClaim": "$.family_name",
    "inputDescriptorId": "familyName_vc"
  },
  {
    "sourceField": "$.issuer",
    "idTokenClaim": "$.custom[0].issuer",
    "inputDescriptorId": "email_vc"
  }
]
Modify ID Token Mapping
  1. Confirm that all details are correct and save the Login Configuration.

  2. After successfully saving the details, a popup will show the Client Credentials (Client ID and Issuer) for your Login Configuration. Copy the generated Client Credentials and configure your app to integrate with Affinidi Login.

  3. After copying the Client ID & Issuer and closing the popup, you are redirected back to the Affinidi Login page.

Login Configuration new client

Connect Affinidi Login with the Social Login App

  1. Open the installed app by clicking on Apps and selecting miniOrange.
miniorange-open-app
  1. Click on SETUP IDP option under miniOrange App, which will take your to miniOrange website, Click on Add Identity Provider button and then click on OAuth 2.0 tab item and enter the below details.
miniorange-app-setup-idp
  • App Name as the Custom Provider
  • App Display Name as Affinidi
  • OAuth Authorize Endpoint as {ISSUER}/oauth2/auth?state=123abcdef (e.g.https://427cc658-ddf8-4e5e-93b3-c038c13fac19.apse1.login.affinidi.io/oauth2/auth?state=123abcdef)
  • OAuth Access Token Endpoint as {ISSUER}/oauth2/token
  • OAuth Get User Info Endpoint as {ISSUER}/userinfo
  • Client ID as your Client ID obtained from your previous step
  • Grant Type as Authorization Code PKCE
  • Scope as openid offline_access
miniorange-test-sso
  1. Click on Save button.

  2. Validate the IdP setting by clicking on Test Connection

Test Integration on Shopify

  1. Visit your Shopify Store website and browse the login page.
  2. Now, one should see the Affinidi Login button.
  3. Click on the button to experience the Affinidi Login based authentication flow.
  4. After successfully logging in, as a Store Admin, you’ll find a new customer automatically created in the Shopify store.
shopify-store-test

You have completed the integration of Affinidi Login to provide a Passwordless Login experience into the Shopify Store with OIDC protocol. This feature will auto-create users and update user attributes like first name, last name, tags, address, etc., from Affinidi Login to your Shopify customer profile.

Optional Setup

Customisation

Depending on the app you choose, you may have options to customise the appearance of the social login buttons to match Affinidi’s style guide. Explore these customisation features if needed.

Customise the Shopify Theme to display Affinidi Login button as per the style guide by Affinidi.

  1. Edit the Theme Code by opening the store -> Online Store -> Theme -> Edit Code
theme edit
  1. Click on option Add a new asset under Assets menu

  2. Create a new Blank file with JS as extension and file name as affinidi-login

create asset file
  1. Copy the below Javascript Code and paste in the above JS file just created and click on Save button

function InitAffinidiLoginUI() {
  var html = `<div class="MOheader" id="MOmyHeader">
    <div class="affinidi-login-div">
      <button class="affinidi-login" onclick="Login_Click()">
          Affinidi Login
      </button>
    </div>
  </div>`;

  // html += `<p style="margin:2rem;font-size:20px;text-align:center;">
  //   <b id="subtextArea">Or</b>
  // </p>`

  var blocks = document.querySelectorAll('#password-modal-heading,.account-register-title,#customer_login_box,#customer_login,#customer_loginlogin-sidebar,#customer_createlogin-sidebar,#create_customer');

  blocks.forEach(block => {
    var div = document.createElement('div');
    div.innerHTML = html;
    block.prepend(div);
  });


}

function Login_Click() {
  event.preventDefault();
  var shop_name = window.location.hostname;
  var queryString = window.location.search;
  console.log(queryString);
  var checkout_url;
  const urlParams = new URLSearchParams(queryString);
  if (urlParams.has('checkout_url')) {
    checkout_url = "/checkout";
  }
  else {
    checkout_url = "/account";
  }

  var cartValue = getCookie("cart");
  if (typeof cartValue !== 'undefined') {
    createCookie("cart", cartValue, 15);
  }

  location.href = "https://store.xecurify.com/moas/broker/login/shopify/" + shop_name + "/account?redirect_endpoint=" + checkout_url;

}

document.addEventListener("DOMContentLoaded", function (event) {
  InitAffinidiLoginUI();
});


function getCookie(cookieName) {
  let cookie = {};
  document.cookie.split(";").forEach(function (el) {
    let [key, value] = el.split("=");
    cookie[key.trim()] = value;
  })
  return cookie[cookieName];
}

function createCookie(name, value, days) {
  if (days) {
    var date = new Date();
    date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
    expires = "; expires=" + date.toGMTString();
  }
  else {
    expires = "";
  }
  document.cookie = name + "=" + value + expires + "; path=/";
}
affinidi login js
  1. Create a new blank file with CSS as extension and file name as affinidi-login

  2. Copy the below CSS code and paste in the CSS file just created and click on Save button

.affinidi-login-div {
  text-align: -webkit-center;
  padding-bottom: 1rem;
}

.affinidi-login-div button {
    border: 0;
    height: 48px;
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
    gap: 12px;
    padding: 12px 20px;
    object-fit: contain;
    border-radius: 48px;
    background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="30" height="24" viewBox="0 0 30 24" fill="none"><path d="M3.927 20.281A11.966 11.966 0 0 0 12.61 24c3.416 0 6.499-1.428 8.684-3.719H3.926h.001zM21.295 6.762H1.813A11.933 11.933 0 0 0 .707 10.48h20.588V6.762zM21.293 3.719A11.967 11.967 0 0 0 12.609 0a11.966 11.966 0 0 0-8.683 3.719h17.367zM21.295 13.521H.707c.167 1.319.548 2.57 1.106 3.719h19.482v-3.718zM23.41 6.762c.558 1.148.94 2.4 1.106 3.718h4.78V6.762H23.41z" fill="%23fff"/><path d="M29.293 20.281h-8V24h8V20.28zM23.41 17.24h5.886v-3.718h-4.78a11.933 11.933 0 0 1-1.106 3.718zM29.293 0h-8v3.719h8V0z" fill="%23fff"/><path d="M24.514 10.48a11.934 11.934 0 0 0-1.106-3.72 12.017 12.017 0 0 0-2.115-3.041v16.563a12.05 12.05 0 0 0 2.115-3.042 11.935 11.935 0 0 0 1.2-5.24c0-.516-.031-1.023-.094-1.522v.001z" fill="%23040822"/></svg>') no-repeat 25px center;
    background-color: #1d58fc;
    color: #ffffff;
    padding-left: 60px;

    flex-grow: 0;
    font-family: 'Figtree', sans-serif;
    font-weight: 600;
    font-stretch: normal;
    font-style: normal;
    line-height: 1.25;
    letter-spacing: 0.6px;
  
    --border-offset: none;
    --border-opacity: none;
}

.affinidi-login-div button:hover {
    background-color: #4a79fd;
    filter: contrast(90%);
}

.affinidi-login-div button:active {
    background-color: #1d58fc;
}
affinidi login css
  1. Open the file theme.liquid file under Layout menu

  2. Paste the below code and paste it at the end of the theme.liquid file (right before the closing of body tag) as mentioned in the screenshot

{{ 'affinidi-login.css' | asset_url | stylesheet_tag }}
<script src="{{ 'affinidi-login.js' | asset_url }}" defer="defer"></script>
theme liquid update
  1. Preview the store and should the see the Login Button
login button
  1. Switch off the Display Widget in miniOrange App, as we have added our own SSO button styling
miniorange toggle off
  1. Uncheck the Captcha option for Login/Register page, to avoid users to select captcha while Login into store.
disable captcha

Monitor and Analyse

Once social login is enabled, monitor its usage and analyse any relevant analytics the app provides. This information can help you understand customer preferences and optimise your store’s user experience. You can monitor usage Analytics from Affinidi Developer Portal as well.