Customer Login and Request Context

Plan: Composable Developer

Lesson 23 of 27 · 30 min

Authenticating Customers with GraphQL

The login mutation in the GraphQL Storefront API serves to authenticate a set of customer credentials. When using the login mutation in a server-to-server context, the mutation will return a customer access token.

If the login mutation request is from a browser, a customer access token will not be returned. Instead, the authenticated session state will be tracked by a cookie.

Example Login Mutation:

mutation Login($email: String!, $pass: String!) {
login(email: $email, password: $pass) {
customer {
entityId
email
}
customerAccessToken {
value
expiresAt
}
}
}

The customer access token will be returned if authentication is successful. Otherwise, an error will be returned in the typical GraphQL response format.

Example Error Response:

{
"data": null,
"errors": [
{
"message": "Invalid credentials",
"path": [
"login"
],
...
}
]
}

Multi-Channel Implications

When multi-channel support is enabled for a store, the GraphQL request context, store settings, and assigned customer channels are all important for customer authentication.

  • Remember that all requests to the GraphQL Storefront API are issued to a URL specific to a channel, so this alone is sufficient to determine which channel the login mutation is authenticating a customer for.
  • The customer settings for a given channel include allow_global_logins, which determines whether login is allowed for customer accounts not assigned to that channel. If this setting is TRUE for the channel you’re logging in on, authentication will succeed regardless of the customer’s assigned channels.
  • If global logins are not enabled for a channel, authentication will only succeed if the customer’s channel_ids field includes that channel.

The error message returned will not indicate whether customer authentication failed because of incorrect credentials or because the customer is not authorized for the channel.

The allow_global_logins setting can only be inspected and set using the REST Management API.

Customer Context in GraphQL Requests

The current customer context is important for a number of GraphQL operations. As previously noted, the basic customer details fetched with the customer query is based on this context rather than any explicit argument.

The customer context is established in one of two ways:

  • Client-side - In a client-side request, the session tracked with the SHOP_SESSION_TOKEN cookie is authenticated with the customer account on a successful login mutation. Subsequent requests then receive this customer context when this cookie is included. As a reminder, it is recommended not to rely on this cookie in your storefront implementation, including for customer session state.
  • Server-side - In a server-side requests, providing a customer access token in the HTTP header X-Bc-Customer-Access-Token establishes the customer on whose behalf the request is made.

The following is an example request with a customer access token.

POST https://{{storeDomain}}/graphql

Headers:

Accept: "application/json"
Content-Type: "application/json"
Authorization: "Bearer {storefront token}"
X-Bc-Customer-Access-Token: {Customer access token}

Body:

query CustomerAttributes($shirtSizeId: Int!, $favoriteColorId: Int!) {
customer {
firstName
lastName
email
entityId
customerGroupId
attributeCount
attributes {
shirtSize: attribute(entityId: $shirtSizeId) {
entityId
value
}
favoriteColor: attribute(entityId:$favoriteColorId) {
entityId
value
}
}
}
}

Note that you can use a customer impersonation token to perform queries or mutations on behalf of any customer by using their userId, but the more secure option is to use the customer access token as shown in the example above. A customer impersonation token must only be used in server-side contexts where they will not be publicly exposed.

The Effects of Customer Context

So far, we’ve examined the relevance of the current customer context to the basic customer query. However, any query or mutation involving potentially customer-specific data will be affected by the same context mechanism.

Including the X-Bc-Customer-Access-Token header in GraphQL requests will have effects in scenarios like the following.

  • Cart and wishlist - All queries and mutations related to carts and wishlists are sensitive to the customer context. If, for example, a cart is initially created on behalf of a certain customer, only subsequent requests with the same customer context will be allowed to access or modify that cart.
  • Product and category visibility - If the customer group a customer belongs to is subject to access restrictions, this will be reflected in the results of all catalog queries. For example, categories the customer does not have access to will not be included in the results of a site.categoryTree query. Products not assigned to a category the customer can access will not be included in the results of a site.search.searchProducts query.
  • Product pricing - Any discounts or pricing lists applicable to a customer’s group will be reflected in all queried product data, as well as factored into totals calculation for the customer’s associated carts. The distinction between the regular price set on a product and the applicable price for the customer context is one of the key differences between the basePrice and price items in a product’s prices field.

Checkout Redirect

When the X-Bc-Customer-Access-Token header is provided when using the createCartRedirectUrls mutation, the resulting redirect URL will not only load the contents of the cart but will also automatically log the user into the corresponding customer session.

Resources