Time-sensitive promotions, flash sales, traffic spikes, and the storefront experience — there are so many details to consider when preparing for high-volume holidays, such as Thanksgiving in the U.S. At Salesforce, trust is our number one value, and it is our top priority this holiday season to support our commerce customers to deliver high scale, always-available and secure shopping experiences to millions of their shoppers.
In order to provide a highly secure login experience, customers who are implementing PWA Kit or SFRA based or the hybrid (part PWA, part SFRA based) storefronts implement The Shopper Login and API service (SLAS) that enables a standard OAuth 2.1 login experience. With SLAS you get Federated or Social login, secure access to shopper APIs, personalized shopping experience using a unique shopper identifier (
USID), and perpetual login or cart persistence.
After a successful login, applications can use the SLAS token to securely call SCAPI and OCAPI end points as part of their commerce applications. At Salesforce, Trust is our #1 value. As part of delivering on this value, we have curated the following best practices for developers using SLAS to level up security and trust in all kinds of headless commerce builds.
Minimize SLAS calls
To make your app more performant and reduce calls to SLAS, consider creating your own USID (unique shopper identifier) and passing this into SLAS. A SLAS USID is simply a UUID type 4 (e.g., see the Online UUID Generator). Avoid calling the SLAS guest flow just to obtain a new USID and then discarding the SLAS Guest JWT. Refer to our prescribed rate limits to ensure that your requests to SLAS end points are within the permissible limits. Guidance in summary:
- Use a private client if you can secure the clientID’s secret
- Persist the USID and refresh tokens for later use
- Reuse the SLAS JWT access token until it is about to expire
Leverage SLAS JWT for shopper information
The SLAS JWT (JSON web token) has information about the shopper, such as their name and login ID. Ensure that the full duration of the SLAS Shopper JWT is used before refreshing the token. Waiting for a 401 error on the SLAS shopper JWT expiration and then refreshing the token adds an extra call. The fewer API calls you use, the better the shopper experience will be. In the context of the SLAS Shopper JWT, this is best achieved by making full use of the lifetime duration of the token. Add a code in your client to read the time at which the JWT was issued (IAT) or the time after which the JWT expires (EXP). Just before the expiration time, call the SLAS refresh token. Note that the SLAS token time to live (TTL) is 30 minutes. Access tokens are invalidated if the customer’s password is updated.
If information about the shopper is needed, you can use the ID token that is in the response of a
SLAS ID token:
An alternative approach for fetching shopper information is to call the
/userinfo (see docs) endpoint. As this creates an additional API call, it is only recommended when you no longer have access to the data of the ID token.
SLAS JWT access tokens are valid for 30 minutes, but the refresh token can be used for up to 90 days on production (nine days on lower level tenants) to request a new access token. With a public client, the refresh token can only be used one time, so it’s important to replace and store the new refresh token that is returned when you request an access token. With a private client, you can reuse the same refresh token repeatedly until it expires, or use the new refresh token that is returned.
Validate JWT efficiently
JSON web token (JWT) claims are pieces of information asserted about a subject. In the example below, the SLAS token contains a claim called
ISB::UIDN that asserts that the shopper name authenticating is “Blair Smith.” Be sure to process the claims based on a key-map pattern versus the order in which they appear.
For example, the JWTs below contain numerous claims:
isb are the important ones.
Prepare for bot attacks
Account takeovers, gift card frauds, bandwidth choking, and inventory exhaustion are just a few of the ways that bots will try to spoil the holiday season for your shoppers. To combat such attacks, add the
X-Forwarded-For header for all the Salesforce Commerce API (SCAPI)/SLAS API calls. The
X-Forwarded-For (XFF) request header is the de-facto standard header for identifying the originating IP address of a client connecting to a web server through a proxy server. Make use of the XFF header and ensure that your backend for frontend stores or CDNs are carrying XFF information into subsequent API calls.
In case of bot attacks, the Salesforce CDN team could also rate limit or rejects calls from that particular IP address, thus saving on rate limit quota for your legitimate API calls.
Ensure that you have the correct Transport Layer Security (TLS) connections when connecting to Salesforce SLAS and SCAPI to avoid man-in-the-middle attacks. This can be achieved by making sure that REST calls have the proper configuration checks set to confirm the server side TLS certificate.
Conduct testing and review error logs
Investigate and document all of your 400 responses that are returned from SLAS and SCAPI calls. These are client-side errors that you can change, and each of the 400 errors that you fix could result in a successful login or refresh. If you run into multiple 429s, then ensure that you are not exceeding two calls for SLAS login. The SLAS API offers two variants for guests and registered login users. Depending on your application type, the guest login is one call for a private client and two calls for a public client. If you are using the
plugin_slas cartridge, ensure that you are on the latest version.
Recently, SCAPI enabled external correlation ID support via the HTTP request header
correlation-id: $UUIDv4, which works with SLAS as well. With the use of this ID, if calls fail, the customer can provide the correlation ID to SFDC support to allow them to pinpoint what went wrong. This ID is returned in the
x-correlation-id HTTP response header as part of the response from SCAPI.
Secure your cookies
Care should be taken to avoid storing SLAS shopper JWTs or SLAS ID tokens in browser local storage. If local storage is in use, it is best to make sure there is a strong Content Security Policy (CSP) in place to help prevent their exfiltration! There are attack vectors when local storage is used that could lead to a loss of PII (personally identifiable information) data. If the JWT or ID token needs to be in the browser, then use a cookie (with
SameSite=strict, see more info). The benefit of using the
HttpOnly flag when generating a cookie helps mitigate the risk of a client-side script accessing the protected cookie.
You can store the refresh token as a cookie (with
SameSite=strict) and use it to gain back the same user context as when the user was logged in.
Protect access credentials
Shopper Login Access Service (SLAS) APIs use credentials for authentication. We recommend that you treat your SLAS client ID and secret/password as confidential material and take measures to secure them. Do not store this information in cookies. As a best practice, get an independent security penetration test to ensure this information is stored safely and securely.
Avoid mixing login calls
The SCAPI /actions/login API (which functions like an IDP) is different from the SLAS Login OAuth IDP. Do not mix an SLAS /authorize and /token flow with any calls to refresh in SCAPI /actions/login. The analogy is that one wouldn’t log in to Google and then send its refresh token to Facebook to authenticate a Google user — SLAS and SCAPI logins are two different IDPs.
Beginning with the Spring ’23 release, the Commerce Cloud API (SCAPI) endpoints related to shopper login will be replaced by the Shopper Login and API Access Service (SLAS) endpoints. They are not available to new customers, and for existing customers, we strongly recommend that you use SLAS because it meets a higher standard for security and availability.
Callbacks and redirects from SLAS
In OAuth authorization code flows for both guest and named user logins, SLAS returns an HTTP redirect (response status code 303) to the provided redirect URI. It is vital to make sure that the customer endpoints that are receiving the SLAS callback be as performant and scalable as possible. SLAS is a high-scale service, and when it gets flooded with guest and named user login requests, it will send out a wave of downstream calls. A receiving service could get overwhelmed and thus potentially impede other shopper logins. The takeaway: code your callback services with the simplest of logic, and consider deferring post processing out of band.
Another option is that if you’re using
plugin_slas (in a pattern where this flow is happening on the backend and not in the browser directly), then it is ok to NOT follow the 303 redirect, but instead, just pull the authCode token from the callback parameters list, then call /token with it — saving you a step and boosting performance!
Our SDKs and the latest version of Plugin SLAS do this out of the box — see the docs for more information.
Browser/client side, you must follow the redirect because of how the
fetch|xmlhttprequest specs work. Server side, you can opt to not follow the redirect. Many frameworks follow redirects by default, so you’ll likely need to disable this. For the Redirect URI itself, you’ll want to host it on something scalable like PWA/ECOM. If you’re building an SPA, the redirect page can be static.
OAuth JSON Web Key Set (JWKS) SLAS API Endpoint
The JSON Web Key Set (JWKS) is a set of keys containing the public keys used to verify any JSON Web Token (JWT) issued by the Authorization Server (SLAS) and signed using the RS256 signing algorithm.
SLAS exposes a JWKS endpoint for each tenant, see the JWKs documentation, which provides the CURRENT public key identified by its key Id (kid). Each JWT header has a kid field that can then be matched against the kid from the JWKs API call – from here the signature can be confirmed. The endpoint is intended for testing and debugging, but explicitly not for validating every SLAS Shopper JWT returned from its /token endpoint as part of a shopper flow. The JWKS endpoint is rate limited to explicitly disallow this pattern. The security model for signed JWT tokens is such that if the caller validates the SLAS TLS server certificate, this means that the token delivered over the network connection did indeed originate at Salesforce and was signed by SLAS. Next, when the SLAS shopper token is sent into the Commerce Cloud SCAPI or OCAPI APIs the token’s signature is checked for correctness (recall if the contents of the JWT is tampered with, the signature check will fail). With both of these security controls in place, it is guaranteed that the token SLAS provides that is then used in the Commerce APIs above can be trusted for that cart, products search, or promotional shopping transaction. The scenario where the JWT was taken into a merchant app and somehow tampered or changed is also covered with the security controls. In this case, the tampered JWT will fail the JWT signature check in the Commerce APIs and be rejected with a 401 unauthorized.
Mobile App and API Protection
Password guessing and credential stuffing is a major concern for eCommerce merchants as they can lead to shopper accounts being taken over which can lead to lost sales and customers. The typical pattern starts with your site experiencing a high rate of 401 errors (ie. 85% to 95% of /logins are all failures), indicating an attacker is using a Bot network to guess usernames and passwords – causing undo traffic and site slowness. A simple, yet effective approach is on the server API side, by enabling WAF Bot protection services that your platform undoubtedly provides. Continuing with a “defense-in-depth” strategy, the following are several, critical security controls every mobile shopping app should have.
- Block static analysis of your Apps login flow, by obfuscating the code AND the actual logic around login and API access to your server backend. Many vendors offer this feature as part of their mobile app hardening product offerings. With this in place, the attacker will be slowed in their research and pre-planning.
- Prevent the app from running in simulators, emulators, or virtual environments. Usually, most mobile app dev environments offer security protections at build and deployment time. Doing so will make it much harder for an attacker to reverse engineer the mobile app to determine how login flows occur and how your backend server API is being called.
- AES-256 encrypts API access keys used inside the mobile app and uses the platform’s provided key management solution to help. Both Apple and Android provide patterns for managing key material in their apps securely.
- Protect the app from Man in The Middle Attacks – by ensuring the app only connects over Mutual TLS. This ensures the app confirms the server is correct via checking its PKI certificate AND vice versa, the server confirms that it is taking connections from your mobile app only.
- Get your mobile app Security Penetration Tested (i.e. pen tested) by a 3rd party vendor with expertise in this space.
With these controls in place, the attacker is sure to be slowed down, get frustrated, and move away from attacking your mobile app and your eCommerce site.
To summarize, there’s more to holiday readiness and ensuring seamless customer (shopper) login experiences that boost revenue and brand reputation. Planning starts way before the festive season officially kicks off. Aim to have your holiday strategy laid out and incorporate best practices for website performance. That way, you don’t risk losing out on customers eager to start their shopping when fall rolls around.
About the authors
Preethika S Kalyanasundaram is a Product Manager at Salesforce. She strives to build great products that are simple, powerful, and geared toward helping people in making their lives better. Connect with her on LinkedIn.
Gregg Ganley is the Commerce Cloud Engineering Security and Identity Architect at Salesforce. Identity and security are his passions, and he works to provide low-friction, trusted authentication flows for customers. Connect with him on LinkedIn.