# 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

- 
You already have a development store created where you would configure Affinidi Login. If you need to create one then follow instructions [here](https://help.shopify.com/en/partners/dashboard/managing-stores/development-stores).

- 
Information presented here is recommended as a learning guide for non-production environments. We recommend to reach out to Affinidi team through [Discord](https://discord.com/invite/hGVVSEASPQ) to assess and adjust the production readiness together for your specific store.

## Before you begin

- 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](https://vault.affinidi.com) or install the Mobile Vault (for [Android](https://play.google.com/store/apps/details?id=com.affinidi.vault&pcampaignid=web_share)).

The same setup steps for Mobile Vault.

- 
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.

GIF 

- Enter your email address to register with the Affinidi Vault. An OTP will be sent to this email for verification.

GIF 

- Enter the OTP sent to the email you have provided for verification to complete the setup.

GIF 

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

Remember to keep your passphrase in a secure location. Use the Passphrase Reset feature in Affinidi Vault settings to generate the PDF files and keep them safe, which you can use to recover access to your Affinidi Vault if you forget your passphrase.

- Install the Affinidi CLI. Follow the guide below if it hasn’t been installed.

        Set up Affinidi CLI

- Download and install [NodeJS](https://nodejs.org/en/download) on your machine if you haven’t set it up yet.

Node Version

Affinidi CLI requires Node version 18 and above.

- Install Affinidi CLI using Node Package Manager (npm).

```bash
npm install -g @affinidi/cli
```

- Verify that the installation is successful.

```bash
affinidi --version
```

- 
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](https://apps.shopify.com/) 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](https://apps.shopify.com/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.

Note

You are solely responsible for paying all fees and taxes (in each case, if any) for any App you obtain from the Shopify App Store. So please select the option carefully and feel free to engage with the Affinidi team on Discord if you have any questions.

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

Click on [miniOrange Single Sign OnSSO](https://apps.shopify.com/single-sign-onsso) app, then click the “Install” button.

Following are more detailed step-by-step instructions:

- 
Go to your [Shopify Admin portal](https://admin.shopify.com) and select your store.

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

- Select Apps and sales channels option and click on Shopify App Store.

- On Shopify App Store page, search for SSO and select miniOrange Single Sign On‑SSO App.

- Click on Install button, which will redirect to your store.

- Click on Install button to install the App in your store. This app requires access to create/read customers record.

- Open the installed app by clicking on Apps menu on left side panel and select miniOrange.

- 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

- 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.

### Create Login Configuration for Social Login App

- 
Go to [Affinidi Login ](https://portal.affinidi.com/login) under the Services section.

- 
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

- 
Customise your Presentation Definition and ID Token Mapping by expanding the Additional Configuration section and clicking on the Create New button

- 
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.

```JSON
{
  "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"
            }
          }
        ]
      }
    }
  ]
}
```

- 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.

```JSON
[
  {
    "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"
  }
]
```

- 
Confirm that all details are correct and save the Login Configuration.

- 
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.

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

### Connect Affinidi Login with the Social Login App

- Open the installed app by clicking on Apps and selecting miniOrange.

- 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.

Enter the below details.

- 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

Note

Replace {ISSUER} with your Issuer obtained from your previous step.

- 
Click on Save button.

- 
Validate the IdP setting by clicking on Test Connection

## Test Integration on Shopify

- Visit your Shopify Store website and browse the login page.

- Now, one should see the Affinidi Login button.

- Click on the button to experience the Affinidi Login based authentication flow.

- After successfully logging in, as a Store Admin, you’ll find a new customer automatically created in the Shopify store.

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](/products/affinidi-elements/affinidi-login/button-styleguide.md). Explore these customisation features if needed.

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

- Edit the Theme Code by opening the store -> Online Store -> Theme -> Edit Code

Note

Take Backup of the theme before making any changes to existing Theme

- 
Click on option Add a new asset under Assets menu

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

- Copy the below Javascript Code and paste in the above JS file just created and click on Save button

```Javascript
function InitAffinidiLoginUI() {
  var html = `

          Affinidi Login

  `;

  // html += `

  //   Or
  // `

  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=/";
}
```

- 
Create a new blank file with CSS as extension and file name as affinidi-login

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

```CSS
.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,') 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;
}
```

- 
Open the file theme.liquid file under Layout menu

- 
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

```Javascript
{{ 'affinidi-login.css' | asset_url | stylesheet_tag }}

```

- Preview the store and should the see the Login Button

- Switch off the Display Widget in miniOrange App, as we have added our own SSO button styling

- Uncheck the Captcha option for Login/Register page, to avoid users to select captcha while Login into store.

### 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.
