> This page is for Developer.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.bigcommerce.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.bigcommerce.com/_mcp/server.

# Customer Login API

## Introduction

In this tutorial, you will learn how to enable single sign-on for storefront customers using the Customer Login API and JSON Web Tokens.

> **Note**
>
> You can also use the [GraphQL Storefront API](/developer/docs/storefront/guides/graphql-storefront-api/authentication#signing-customers-in) to authorize your application to work with customer-specific storefront data.

## Overview

Single sign-on (SSO) is an authentication mechanism that enables users to sign in to multiple software applications using the same set of credentials that the user enters only once. It eliminates the need to maintain multiple passwords, which streamlines the process of accessing web applications. For more details, see [Single Sign-On](https://en.wikipedia.org/wiki/Single_sign-on).

When a user signs into your web app, you can use the Customer Login API to authenticate the user to your BigCommerce store through SSO.

You can use the Customer Login API in the following use cases:

* Integrate with an SSO provider or identity provider (IdP)
* Set up continuous login between a BigCommerce store and another application
* Enable alternative sign-in methods (ex. phone number and SMS password)

Storefront customers are signed in using the access point URL `/login/token/{token}`. The `{token}` must be a JSON Web Token (JWT) containing parameters for the customer login request signed by your application’s OAuth client secret. For more information on the OAuth protocol, see [OAuth](https://oauth.net/2/).

JWT is an industry standard ([RFC 7519](https://tools.ietf.org/html/rfc7519)) for securely transmitting information between two parties. A JWT is a sequence of base64url-encoded strings separated by dots (`.`). The sections include the header, payload, and signature. For more details, see [Introduction to JSON Web Tokens](https://jwt.io/introduction/).

> **Note**
>
> A customer account has a single active storefront session. Signing the customer in again or signing them out through any method invalidates all customer access tokens previously issued for that account, regardless of each token's `expiresAt` value. For details, see [Customer session behavior](#customer-session-behavior).

### Customer Login JWT payload reference

| Field Name               | Type               | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| :----------------------- | :----------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `iss`                    | string             | The *issuer*; The API account's client ID.                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `iat`                    | integer, UNIX time | The *issued at* time; when the JWT was issued.                                                                                                                                                                                                                                                                                                                                                                                                             |
| `jti`                    | string, UUID       | The *JWT ID*; a unique identifier for the JWT.                                                                                                                                                                                                                                                                                                                                                                                                             |
| `operation`              | string             | The value is always `customer_login`                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `store_hash`             | string             | The store hash identifying the store the shopper is signing in to.                                                                                                                                                                                                                                                                                                                                                                                         |
| `channel_id`             | integer            | Optional field containing the `channel_id` corresponding to the storefront the shopper is signing in to. Depending on your implementation, omitting the `channel_id` can lead to CORS errors; for example, see [Managing Carts](/developer/docs/storefront/headless/cart-and-checkout/carts#channel-id-is-mandatory). You must include the `channel_id` when using JWTs to embed checkout on a headless storefront. The default `channel_id` value is `1`. |
| `customer_id`            | integer            | The ID of the shopper who is signing in.                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `redirect_to`            | string             | Optional field containing a relative path for the shopper's destination after sign-in. Defaults to `/account.php`.                                                                                                                                                                                                                                                                                                                                         |
| `request_ip`             | string             | Optional field containing the expected IP address for the request. If provided, BigCommerce will check that it matches the browser trying to sign in.                                                                                                                                                                                                                                                                                                      |
| `enable_persistent_cart` | boolean            | Optional field specifying whether or not to use persistent cart functionality on customer token login. This feature depends on you enabling the [Persistent Cart](https://support.bigcommerce.com/s/article/Persistent-Cart) setting on your store. The default value is `false`. The system ignores this value if you use the server-side GraphQL JWT login mutation.                                                                                     |

## Prerequisites

To enable SSO using the Customer Login API, you will need the following:

* A BigCommerce store
* API client ID and client secret with the OAuth Scope set to Customers Login
* [Node.js](https://nodejs.org/en/) installed on your machine if you plan to use JavaScript

Be sure to set the Customers Login scope to Login.

![Example OAuth Scope](/_fern-img/f5186cc69982071d789e3e0723da136cc9671e2e0de330d48ccda35530620cef.webp)

> **Note**
>
> #### API account notes
>
> * This endpoint requires **store-level API account** credentials. For more information about generating accounts, consult the [Guide to API Accounts](/developer/docs/overview/api-fundamentals/api-accounts#store-level-api-accounts).
> * The app you create needs to be installed or published on a store to be able to generate store-level access tokens. All you would need are the client ID and client secret. See the section on [client ID-based authentication](/developer/docs/overview/api-fundamentals/api-accounts#client-id) in the Authentication tutorial.

## Enable single sign-on

To sign a customer in to their storefront account using the Customer Login API, your app needs to redirect the customer’s browser to the following access point URL: `https://storedomain.com/login/token/{token}`.

The `{token}` parameter is the JWT containing the payload data signed by your app’s OAuth client secret.

We recommend writing a script to generate a login token since the JWT’s `iat` (issued at) claim is only valid for 30 seconds. BigCommerce supplies helper methods for generating login tokens in our [API Client Libraries](/developer/docs/overview/tools-and-sdks).

The beginning of this tutorial focuses on manually creating a token using the debugger tool at [JWT.io](https://jwt.io/). Then, we will explore how to use a JavaScript function to programmatically generate an access point URL.

### Create JWT using the debugger tool

To create a JWT, you will need to obtain a `customer_id` using the [Customers v3 API](/developer/api-reference/rest/admin/management/customers/v3).

1. Send a `GET` request to the [Get All Customers](/developer/api-reference/rest/admin/management/customers/v3/get-customers) endpoint. Choose a customer and make note of the `customer_id`.

```json showLineNumbers={false}
{
    "accepts_product_review_abandoned_cart_emails": true,
    "authentication": {
      "force_password_reset": false
    },
    "company": "BigCommerce",
    "customer_group_id": 2,
    "date_created": "2020-02-06T17:46:33Z",
    "date_modified": "2020-02-07T19:58:03Z",
    "email": "customer@email.com",
    "first_name": "Jane",
    "id": 1,    // customer_id
    "last_name": "Doe",
    "notes": "",
    "phone": "",
    "registration_ip_address": "",
    "tax_exempt_category": "D"
}
```

2. Open the debugger at [JWT.io](https://jwt.io/).

3. In the "HEADER" field, make sure the JWT `alg` (algorithm) field is set to `"HS256"` and the `typ` (token type) field is set to `"JWT"`.

![JWT Header](/_fern-img/2c0a692fdf16ac22f99d5449f63293b8d12b9a6c002009cd736d17ee87af75aa.webp)

4. In the "PAYLOAD: DATA" field, create a payload.

![JWT Payload](/_fern-img/45d1e098357b94bf3a9feda938181757da89dac8fb642a190ada7be44b29f211.webp)

5. In the "VERIFY SIGNATURE" field, replace “your-256-bit-secret” with your Client Secret.

![JWT Signature](/_fern-img/d7c081c5a54c462b59cd39e338355de8133ed4f94e51b76ff912a6c5a6d51356.webp)

6. Copy the login token from the encoded box and paste it into the access point URL, replacing the `{token}` parameter.

Example:

```http showLineNumbers={false}
https://storedomain.com/login/token/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ7Y2xpZW50X2lkfSIsImlhdCI6MTUzNTM5MzExMywianRpIjoie3V1aWR9Iiwib3BlcmF0aW9uIjoiY3VzdG9tZXJfbG9naW4iLCJzdG9yZV9oYXNoIjoie3N0b3JlX2hhc2h9IiwiY3VzdG9tZXJfaWQiOjJ9.J-fAtbjRFGdLsT744DhoprFEDqIfVq72HbDzrbFy6Is
```

7. Paste the URL into the address bar of your web browser.

If the request was successful, you will be signed in as a customer and directed to `/account.php`. If it was unsuccessful, a sign in attempt error message will be displayed, and you will be directed to `/login.php`.

![Login Error](/_fern-img/24e19606ecc06cf1a935fa265807a9e3fceebff295196e3e5c449862f7e69ae1.webp)

For common causes of sign-in failure, see [Troubleshooting](#troubleshooting).

### Create JWT using a JavaScript function

In this part of the tutorial, we will walk you through creating an access point URL using JavaScript. You will need [node.js](https://nodejs.org/en/) installed on your machine to complete this section.

1. Create and open a new folder by running the following commands in your terminal:

```bash showLineNumbers={false}
$ mkdir urlGenerator
$ cd urlGenerator
```

2. Create a new node project with the following command:

```bash showLineNumbers={false}
$ npm init
```

3. Install [jsonwebtoken](https://www.npmjs.com/package/jsonwebtoken) and [uuid](https://www.npmjs.com/package/uuid) npm packages:

```bash showLineNumbers={false}
$ npm install jsonwebtoken uuid
```

4. Open the `urlGenerator` folder in your code editor of choice and create a new JS file.

5. Paste the following code into the new JS file:

```js showLineNumbers={false}
const jwt = require('jsonwebtoken');
const {v4: uuidv4} = require('uuid');

function getLoginUrl(customerId, storeHash, storeUrl, clientId, clientSecret) {
   const dateCreated = Math. round((new Date()). getTime() / 1000);
   const  payload = {
       "iss": clientId,
       "iat": dateCreated,
       "jti": uuidv4(),
       "operation": "customer_login",
       "store_hash": storeHash,
       "customer_id": customerId,
   }
   let token = jwt.sign(payload, clientSecret, {algorithm:'HS256'});
   return `${storeUrl}/login/token/${token}`;
};

const clientId = "Your client id";
const clientSecret = "Your client secret";
const customerId = "Your customer id";
const storeHash = "Your store hash";
const storeUrl = "Your store url";

const loginUrl = getLoginUrl(customerId, storeHash, storeUrl, clientId, clientSecret);
console.log(loginUrl);
```

6. Replace your app and customer-specific values in the variables.

7. Run the code:

```bash showLineNumbers={false}
$ node youFileName.js
```

You should receive a complete access point URL as an output.

8. Copy the URL and paste it into the address bar of your browser.

If the request was successful, you will be signed in as a customer and directed to `/account.php`. If it was unsuccessful, you will receive a sign in attempt error message and be directed to `/login.php`. For common causes of sign in failure, see [Troubleshooting](#troubleshooting).

### Sample code

Helper methods for generating login tokens are provided in our [API Client Libraries](/developer/docs/overview/tools-and-sdks). See the following BigCommerce repositories for language-specific examples:

* [PHP sample](https://github.com/bigcommerce/bigcommerce-api-php/blob/master/src/Bigcommerce/Api/Client.php#L421)
* [Python sample](https://github.com/bigcommerce/bigcommerce-api-python/blob/master/bigcommerce/customer_login_token.py)
* [Ruby sample](https://github.com/jordanarldt/ruby-bc-customer-sso-generator/)

For client libraries in other languages, see [Libraries for Token Signing/Verification](https://jwt.io/#libraries-io).

### Signing out

To sign a customer out, set the `redirect_to` field of the JWT’s payload to `/login.php?action=logout`.

## Customer session behavior

The platform maintains a single active storefront session per customer account. When a customer signs in again, the platform rotates the underlying session token and invalidates every customer access token previously issued for that customer. This applies no matter which sign-in method the customer uses, for example:

* A storefront sign-in
* The Customer Login API access point URL, `/login/token/{token}`
* The GraphQL Storefront API [login mutations](/developer/docs/storefront/guides/graphql-storefront-api/authentication#customer-access-tokens), `login` and `loginWithCustomerLoginJwt`
* Sign-in flows built on these methods, such as a B2B Edition buyer portal sign-in

Signing out invalidates the customer access token in the same way. A customer access token's `expiresAt` value is the latest possible expiry time, not a guaranteed lifetime. A token can stop working earlier because the customer signed in again or signed out.

> **Note**
>
> Requests that carry an invalidated customer access token do not fail. The GraphQL Storefront API processes the request as an anonymous shopper: the `customer` field returns `null`, and customer-specific values, such as pricing based on the customer's customer group, fall back to guest values. To make such requests return an explicit error instead, send the `X-BC-Error-On-Invalid-Customer-Access-Token` header with a value of `true`.

If you maintain a headless storefront or an integration that stores customer access tokens, design for this behavior:

* Store at most one customer access token per customer account, and replace it with the newest token after each sign-in.
* Consolidate a customer's sign-in flows on a single method. Each additional sign-in path rotates the token and ends the customer's other sessions.
* Treat a `null` `customer` response as a signal that the customer's session ended, and prompt the customer to sign in again.

## Troubleshooting

* If the clock of the server generating the “iat” claim is not synchronized, the timestamp will be out of sync and the request will fail. If your system’s time is different from the BigCommerce server time, you can use the [Get System Timestamp](/developer/api-reference/rest/admin/management/store-information/v2/get-system-timestamp) endpoint as a source of truth.
* You can only visit the access point URL once. The token will be invalidated after the `GET` request is made.
* Tokens should not be generated in advance. Instead, the app should generate the token and immediately redirect the user’s browser to the access point URL.
* If a customer's requests return `null` for the `customer` field or customer-specific pricing stops applying, check whether the customer signed in again or signed out elsewhere. Each sign-in rotates the session token and invalidates previously issued customer access tokens. See [Customer session behavior](#customer-session-behavior).

## Related resources

### Articles

* [Authenticating BigCommerce’s REST APIs](/developer/docs/overview/api-fundamentals/api-accounts#choosing-the-right-kind-of-api-account)
* [BigCommerce APIs Quick Start](/developer/docs/overview/quick-start)
* [Introduction to JSON Web Tokens](https://jwt.io/introduction/)

### Endpoints

* [Customer Login SSO](/developer/api-reference/rest/admin/authentication-apis/customer-login-api)
* [Customers V3](/developer/api-reference/rest/admin/management/customers/v3)