Magento 2 + MojoAuth (OIDC)
This guide shows how to integrate MojoAuth with Magento 2 using the standard OpenID Connect Authorization Code flow. We’ll use a lightweight PHP OIDC client, then wire it into Magento routes/controllers so customers can sign in via the MojoAuth Hosted Login Page.
- Platform: Magento 2.4+
- Language: PHP 8.1+
- Protocol: OpenID Connect (OIDC)
- Flow: Authorization Code (with PKCE recommended)
- Library:
jumbojett/openid-connect-php
References
- MojoAuth Hosted Login Page: https://docs.mojoauth.com/hosted-login-page/ (opens in a new tab)
- PHP OIDC client (jumbojett): https://github.com/jumbojett/OpenID-Connect-PHP (opens in a new tab)
- Magento 2 DevDocs (modules/controllers): https://developer.adobe.com/commerce/docs/ (opens in a new tab)
Prerequisites
- Magento 2.4+ instance with admin access
- Composer access on the server
- MojoAuth OIDC app with:
- Client ID
- Client Secret
- Issuer:
https://api.mojoauth.com - Redirect URI:
https://yourstore.com/mojoauth/callback
1) Install the OIDC Library
Install the PHP OIDC client with Composer:
composer require jumbojett/openid-connect-php2) Configure Environment Variables
Set configuration via Magento env.php or system environment variables:
// app/etc/env.php (example snippet) return [ 'mojoauth' => [ 'issuer' => 'https://api.mojoauth.com', 'client_id' => 'your-client-id', 'client_secret' => 'your-client-secret', 'redirect_uri' => 'https://yourstore.com/mojoauth/callback', 'scopes' => ['openid', 'profile', 'email'] ], ];Store secrets securely (do not commit to VCS). You can also use Magento config or environment variables.
3) Create a Magento Module (Routes + Controllers)
Create a simple module, e.g., Vendor/MojoAuth with two routes:
/mojoauth/login– starts the OIDC flow/mojoauth/callback– handles the callback and logs the user in
etc/module.xml
<?xml version="1.0"?> <!-- app/code/Vendor/MojoAuth/etc/module.xml --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Vendor_MojoAuth" setup_version="1.0.0" /> </config>etc/frontend/routes.xml
<?xml version="1.0"?> <!-- app/code/Vendor/MojoAuth/etc/frontend/routes.xml --> <routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd"> <route id="mojoauth" frontName="mojoauth"> <module name="Vendor_MojoAuth" /> </route> </routes>Controller/Login/Index.php
<?php namespace Vendor\MojoAuth\Controller\Login; use Magento\Framework\App\Action\Action; use Magento\Framework\App\Action\Context; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Controller\ResultFactory; use Jumbojett\OpenIDConnectClient; class Index extends Action { public function __construct( Context $context, private ScopeConfigInterface $scopeConfig ) { parent::__construct($context); } public function execute() { $cfg = $this->getConfig(); $oidc = new OpenIDConnectClient( $cfg['issuer'], $cfg['client_id'], $cfg['client_secret'] ); $oidc->setRedirectURL($cfg['redirect_uri']); $oidc->addScope($cfg['scopes']); // Optional: PKCE $oidc->setCodeChallengeMethod('S256'); $oidc->authenticate(); // will redirect to MojoAuth Hosted Login Page return $this->resultFactory->create(ResultFactory::TYPE_RAW); } private function getConfig(): array { // Load from env.php or Magento config return [ 'issuer' => 'https://api.mojoauth.com', 'client_id' => $this->scopeConfig->getValue('mojoauth/general/client_id'), 'client_secret' => $this->scopeConfig->getValue('mojoauth/general/client_secret'), 'redirect_uri' => $this->_url->getUrl('mojoauth/callback/index'), 'scopes' => ['openid','profile','email'], ]; } }Controller/Callback/Index.php
<?php namespace Vendor\MojoAuth\Controller\Callback; use Magento\Framework\App\Action\Action; use Magento\Framework\App\Action\Context; use Magento\Customer\Api\CustomerRepositoryInterface; use Magento\Customer\Api\AccountManagementInterface; use Magento\Customer\Model\Session as CustomerSession; use Magento\Framework\Controller\ResultFactory; use Magento\Store\Model\StoreManagerInterface; use Jumbojett\OpenIDConnectClient; class Index extends Action { public function __construct( Context $context, private CustomerRepositoryInterface $customerRepo, private AccountManagementInterface $accountMgmt, private CustomerSession $customerSession, private StoreManagerInterface $storeManager ) { parent::__construct($context); } public function execute() { $cfg = $this->getConfig(); $oidc = new OpenIDConnectClient( $cfg['issuer'], $cfg['client_id'], $cfg['client_secret'] ); $oidc->setRedirectURL($cfg['redirect_uri']); $oidc->addScope($cfg['scopes']); $oidc->setCodeChallengeMethod('S256'); // Complete code exchange and get tokens $oidc->authenticate(); // Get user profile $email = $oidc->requestUserInfo('email'); $name = $oidc->requestUserInfo('name'); $given = $oidc->requestUserInfo('given_name'); $family = $oidc->requestUserInfo('family_name'); if (!$email) { // handle error return $this->resultFactory->create(ResultFactory::TYPE_REDIRECT) ->setPath('customer/account/login'); } // Find or create Magento customer try { $customer = $this->customerRepo->get($email); } catch (\Exception $e) { // Create new customer account $websiteId = (int)$this->storeManager->getWebsite()->getId(); $customer = $this->accountMgmt->createAccount( (new \Magento\Customer\Model\Data\Customer()) ->setEmail($email) ->setFirstname($given ?: ($name ?: '')) ->setLastname($family ?: '-') ->setWebsiteId($websiteId), // Random password; not used if you keep passwordless bin2hex(random_bytes(12)) ); } // Log in customer session $this->customerSession->setCustomerDataAsLoggedIn($customer); return $this->resultFactory->create(ResultFactory::TYPE_REDIRECT) ->setPath('customer/account'); } private function getConfig(): array { return [ 'issuer' => 'https://api.mojoauth.com', 'client_id' => getenv('MOJOAUTH_CLIENT_ID') ?: '', 'client_secret' => getenv('MOJOAUTH_CLIENT_SECRET') ?: '', 'redirect_uri' => $this->_url->getUrl('mojoauth/callback/index'), 'scopes' => ['openid','profile','email'], ]; } }Register the module:
php bin/magento setup:upgrade php bin/magento cache:flush4) Configure MojoAuth Redirect URIs
In the MojoAuth Dashboard → OIDC App settings:
- Allowed Callback URLs:
https://yourstore.com/mojoauth/callback - Allowed Logout URLs:
https://yourstore.com/customer/account/logoutSuccess/ - Allowed Origins (CORS):
https://yourstore.com - Scopes:
openid profile email
5) Add Login Button
- Add a header link or button pointing to
/mojoauth/login - Optionally, override Magento login page template to show "Login with MojoAuth"
Example (PHTML snippet):
<a class="action login sso" href="<?= $block->getUrl('mojoauth/login/index'); ?>"> Login with MojoAuth </a>6) Test the Flow
- Click "Login with MojoAuth"
- Authenticate on the MojoAuth Hosted Login Page (Magic Link / OTP / Passkey)
- You’ll return to Magento and be logged into your customer account
Troubleshooting
- Callback mismatch: Ensure the Magento callback matches in MojoAuth settings
- 401/invalid_client: Verify Client ID/Secret and Issuer (
https://api.mojoauth.com) - Missing email/name: Ensure
profileandemailscopes and claim mapping - Session issues: Confirm
Magento\Customer\Model\Sessionis used after successful auth - HTTPS: Ensure valid HTTPS in local/staging (self-signed may cause callback issues)
Next Steps
- Map custom claims to customer attributes
- Enforce SSO by redirecting native login to
/mojoauth/login - Add logout endpoint (front-channel/back-channel) if needed
- Multi-store: Use per-store Client IDs or routing for different brands