eCommerce
Magento

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


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-php

2) 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:flush

4) 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

  1. Click "Login with MojoAuth"
  2. Authenticate on the MojoAuth Hosted Login Page (Magic Link / OTP / Passkey)
  3. 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 profile and email scopes and claim mapping
  • Session issues: Confirm Magento\Customer\Model\Session is 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