less than a minute read • Updated 10 minutes ago
Set up SSO between the customer portal and checkout
How to keep customers logged in when they move from the customer portal to checkout.
By default, a customer who logs in to the customer portal isn’t automatically logged in to checkout. Setting up SSO between the two closes that gap, so customers don’t have to log in twice. How you set this up depends on whether you already use SSO elsewhere on your site.
Notes before you start
This requires SSO to be enabled in your Foxy admin’s advanced settings.
If you already use SSO for other purposes (like checking inventory or verifying cart contents), enabling it in the portal bypasses your own endpoint for this flow.
Standalone SSO with the portal
Use this approach if you’re not using SSO anywhere else on your site.
When a customer’s session includes SSO (which happens by default with the standard portal setup), a GET /s/customer?sso=true request returns a _links["fx:checkout"].ref URL that logs the customer into checkout, and sets a cookie named fx.customer.sso.
Steps
<!doctype html>
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<title>SSO Redirect</title>
<meta name="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
<script>
function parseJWT(token) {
let base64Url = token.split('.')[1];
let base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
let jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
return JSON.parse(jsonPayload);
}
function getSSOUrl() {
var value = "; " + document.cookie;
var parts = value.split("; " + "fx.customer.sso" + "=");
if (parts.length == 2) return decodeURIComponent(parts.pop().split(";").shift());
try {
let sessionStore = JSON.parse(localStorage.getItem("session"));
if (sessionStore && sessionStore.hasOwnProperty("jwt")) {
let sessionData = parseJWT(sessionStore.jwt);
let expires = Math.floor(new Date(sessionStore.date_created).getTime() / 1000) + sessionStore.expires_in;
if (
expires > Math.floor(Date.now() / 1000) &&
sessionData.hasOwnProperty("customer_id") &&
sessionStore.hasOwnProperty("sso")
) {
return sessionStore.sso;
}
}
} catch (error) {
console.log("Error trying to get SSO URL:", error);
}
return false;
}
function getUrlParameter(name) {
return new URLSearchParams(location.search).get('fcsid');
}
if (getSSOUrl()) {
window.location.replace(getSSOUrl() + "&fcsid=" + getUrlParameter("fcsid"));
} else {
window.location.replace("https://YOUR_FOXY_DOMAIN/checkout?fc_customer_id=0×tamp=1893456000&fc_auth_token=REPLACE_THIS&fcsid=" + getUrlParameter("fcsid"));
}
</script>
</head>
<body></body>
</html>
This page must be publicly accessible. If you’re inserting this into an existing template instead of using the page as-is, keep only the <script> block, make sure the page is set to not be indexed by search engines, and strip out any unnecessary CSS or JavaScript so it loads as fast as possible.
Incorporating portal SSO with an existing SSO endpoint
Use this approach if you already have SSO enabled and configured on your site. There’s no single set of steps here, since integrations vary, but the general approach is:
Create the portal session and cookie when a customer logs in. When a customer submits their username and password, make a
POST /s/customer/authenticaterequest with those credentials, then store the JSON response in alocalStorageitem namedsession. This requires the customer’s Foxy password to stay in sync with your own auth system.If you don’t have access to the customer’s password, use your store’s configured UOE password instead. This should only ever be used server-side — never expose it in the browser.
Unlike checkout, you likely don’t want to let a customer log in to the portal if they aren’t already logged in to your own system. Instead, redirect them to your login page so they end up fully logged in to your system (rather than just to the Foxy customer portal).