@improntus/saas-app-storefront-okta-integration
v1.0.1
Published
Okta SSO block integration for Adobe Commerce dropins storefronts on AEM Edge Delivery Services.
Readme
@improntus/saas-app-storefront-okta-integration
Okta SSO for Adobe Commerce drop-ins storefronts on AEM Edge Delivery Services.
The storefront delegates sign-in, sign-out and password management to Okta. This package
ships the improntus-okta-integration block and patches the host files that have to call
into it.
The backend is the App Builder app saas-app-okta-integration, which exposes the
okta/login, okta/callback, okta/logout and okta/graphql actions. This package is
useless on its own — the app has to be deployed and configured first.
What it does
| Feature | How |
|---|---|
| Login | "Log in with Okta" button → popup to okta/login → postMessage from okta/callback carrying the customer token |
| Native login replaced | With Okta enabled the drop-in sign-in form is not rendered at all — it is not hidden with CSS |
| Federated logout | Revokes the Commerce token, clears the session cookies and redirects to okta/logout so the IdP session ends too |
| Change password | Button in Customer information → popup to the Okta dashboard |
| Forgot password | Intercepts the native links and the /customer/forgotpassword page → Okta recovery flow |
Everything degrades to the native behaviour when Okta is disabled in App Management.
Requirements
- An EDS storefront with the standard structure (
blocks/,scripts/,config.json). - The auth drop-in (
@dropins/storefront-auth) and the account drop-in (@dropins/storefront-account). - The
saas-app-okta-integrationApp Builder app deployed, with Enable Okta SSO on and the storefront origin listed under Allowed storefront origins.
Installation
From the storefront root:
npm install @improntus/saas-app-storefront-okta-integrationpostinstall copies the block and patches the host files. It resolves the storefront root
from INIT_CWD / npm_config_local_prefix, so it targets your project and not
node_modules.
To re-run it later — after an upgrade, or once you have resolved a manual follow-up item:
npx storefront-okta-integration-installEvery edit is idempotent: each one is skipped when its marker is already in the file, so running the installer twice never duplicates code.
What the installer changes
| File | Edit |
|---|---|
| blocks/improntus-okta-integration/** | copied from the package |
| blocks/commerce-login/commerce-login.js | renders the Okta block instead of SignIn when Okta is on |
| blocks/header/renderAuthDropdown.js | same for the header dropdown, plus federated logout |
| blocks/header/renderAuthCombine.js | same for the AuthCombine modal, plus federated logout |
| blocks/commerce-forgot-password/commerce-forgot-password.js | redirects the recovery page to Okta |
| blocks/commerce-customer-information/commerce-customer-information.js | adds the change-password button |
| config.json | adds public.default.okta-integration and prompts for app-base-url |
If a file is missing or does not match the expected boilerplate, the installer does not
guess: it prints the exact manual step in the install report and moves on. The block
README that ships in blocks/improntus-okta-integration/README.md has the full snippets.
When app-base-url is missing
Without it the block cannot reach the runtime, so it falls back to the native login form — the storefront keeps working instead of being left with no way to sign in. Because a silent fallback looks exactly like a correctly configured site, the block also renders a visible notice next to the form:
Okta SSO is not configured: set "okta-integration.app-base-url" in config.json.
Only this case is surfaced on screen. A network failure or a backend blip is transient and stays in the console — painting a banner for every hiccup would be worse than the log.
config.jsonis cached insessionStorageunder theconfigkey. After editing it, a normal reload keeps reading the stale copy for the life of the tab. Open a new tab, or runsessionStorage.removeItem('config')and reload. This is the usual reason a freshapp-base-urldoes not seem to take effect.
Two edits worth understanding
clearCommerceSessionCookies() is not optional. revokeCustomerToken() invalidates the
token server-side but does not delete the auth_dropin_* cookies, and the storefront decides
whether there is a session by reading auth_dropin_user_token. Without it the user still
looks signed in, holding an already-revoked token.
Replacing AuthCombine also removes native registration. AuthCombine bundles sign in,
sign up and reset password. That is coherent when accounts are created in Okta and synced
into Commerce. If you need to keep native sign-up, render AuthCombine with only
signUpFormConfig instead of skipping it.
Configuration
config.json, under public.default:
{
"public": {
"default": {
"headers": {
"cs": {
"Magento-Store-Code": "store_b2b",
"Magento-Store-View-Code": "store_view_b2b"
}
},
"okta-integration": {
"app-base-url": "https://1234567-myapp.adobeioruntime.net",
"redirect-to-account-after-login": "0",
"login-title-text": "",
"login-button-text": "Log in with Okta account",
"forgot-password-text": "Forgot your password?",
"change-password-text": "Change password in Okta"
}
}
}
}| Key | Required | Notes |
|---|---|---|
| app-base-url | Yes | App Builder runtime URL. npm run urls in the backend project prints it |
| headers.cs.Magento-Store-Code | Yes | Identifies the configuration scope in App Management |
| headers.cs.Magento-Store-View-Code | Yes | Store header for the GraphQL queries |
| redirect-to-account-after-login | No | "1" goes to the account page; "0" reloads |
| post-logout-redirect-uri | No | Local override; otherwise it comes from App Management |
| login-button-text | No | Login button label |
| login-title-text | No | Heading above the button. Omitted when equal to the button label; leave empty for none |
| forgot-password-text | No | Recovery link label |
| change-password-text | No | Change-password button label |
Magento-Store-View-Codeis a silent-failure trap. Customers belong to a website. If theStoreheader points at a store view of a different website, thecustomerquery returns empty fields instead of an error, and it looks like a token problem.
The installer never overwrites values that are already present, so upgrading is safe.
Backend and Okta setup
In App Management → Okta SSO Settings:
| Field | Why |
|---|---|
| Enable Okta SSO | Master switch |
| Issuer URL, Client ID, Redirect URI | The OIDC login app |
| Allowed storefront origins | Fail-closed: without the storefront origin no token is ever emitted |
| Post-logout redirect URI | Where Okta returns after sign-out |
In Okta, on the OIDC app:
| Setting | Value |
|---|---|
| Sign-in redirect URIs | The okta/callback URL |
| Sign-out redirect URIs | The post-logout destination, exact — path and trailing slash included |
| Assignments | The user or group assigned to the app |
| Authorization server → Access Policies | At least one policy with an Authorization Code rule. Without it login fails with "You do not have permission to access this application" |
Contracts
Login popup postMessage:
| Event | type | Payload |
|---|---|---|
| Success | improntus-okta-login-success | { token, idToken } |
| Error | improntus-okta-login-error | { code, message } |
The origin must match okta-integration.app-base-url. idToken is the id_token_hint Okta
requires to end a session, and the block persists it in the okta_id_token cookie.
| Error code | Meaning |
|---|---|
| CUSTOMER_NOT_REGISTERED | The Okta email has no matching Commerce customer |
| invalid_state | PKCE state expired or reused |
| RETURN_URL_NOT_ALLOWED | The origin is not in Allowed storefront origins |
Uninstalling
The installer only adds code, so removing it is manual:
- Delete
blocks/improntus-okta-integration/. - Revert the Okta imports and calls in the five host files above.
- Remove
public.default.okta-integrationfromconfig.json. npm uninstall @improntus/saas-app-storefront-okta-integration.
License
Apache-2.0
