beastbytes / yii-totp
Time-based One Time Password (TOTP) library for Yii3
dev-master
2025-04-07 20:51 UTC
Requires
- php: >=8.1
- ext-gd: *
- chillerlan/php-qrcode: ^5.0
- httpsoft/http-message: ^1.0
- spomky-labs/otphp: ^11.0
- symfony/clock: ^v7.0
- yiisoft/cookies: ^1.0
- yiisoft/db: ^1.2
- yiisoft/definitions: ^3.0
- yiisoft/form: ^1.0
- yiisoft/form-model: ^1.0
- yiisoft/security: ^1.0
- yiisoft/translator: ^3.0
- yiisoft/user: ^2.0
- yiisoft/view: ^12.0
Requires (Dev)
- phpunit/phpunit: ^10.0
- rector/rector: ^1.0
- vimeo/psalm: ^6.0
- yiisoft/cache: ^3.0
- yiisoft/db-migration: ^1.0
- yiisoft/db-sqlite: ^1.0
- yiisoft/injector: ^1.0
- yiisoft/test-support: ^3.0
- yiisoft/translator-extractor: ^2.0
This package is auto-updated.
Last update: 2025-04-07 20:53:29 UTC
README
BeastBytes Yii TOTP simplifies integrating Two-Factor Authentication (2FA) using TOTP (Time-based One-Time Password) into Yii3 applications.
Requirements
- PHP 8.1 or higher.
Installation
composer require beastbytes/yii-totp
or add the following to the 'require' section composer.json:
"beastbytes/yii-totp": "<version-contraint>"
Usage
The application interacts with TotpService
.
NOTE: Code examples show only the core functionality; they do not show dependency injections, support methods, ...
Configuration
The default configuration works with authenticator apps such as Google Authenticator, Aegis, etc.
Enable TOTP
// Totp Controller public function enable( CurrentUser $currentUser, FormHydrator $formHydrator, ServerRequestInterface $request, ): ResponseInterface { $formModel = new OtpForm($this->totpService); if ($formHydrator->populateFromPostAndValidate($formModel, $request)) { $this->redirct('ShowBackupCodes'); } ['qrCode', 'secret'] = $this->totpService->createTotp($currentUser->getId()); return $this->viewRenderer->render( 'enable2faView', [ 'formModel' => $formModel, 'qrCode' => $qrCode, 'secret' => $secret, ] ); }
// enable TOTP View <p>Either scan the QR Code or manually enter the <abbr title='Two‐Factor Authentication'>2FA</abbr> code into your 2FA app, then enter the <abbr title='One‐Time Password'> OTP</abbr> code generated by the app.</p> <img src="<?=$qrCode?>" alt="QR Code" height="400px" width="400px" /> <div>2FA Code</div> <div><?= $secret ?></div> <?= $form ->post($url) ->csrf($csrf) ->open() ; ?> <?= Field::text($formModel, 'code') ?> <?= Field::submitButton('Verify') ?> <?= $form->close() ?>
Verify TOTP
// Totp Controller public function verify( CurrentUser $currentUser, FormHydrator $formHydrator, ServerRequestInterface $request, ): ResponseInterface { $formModel = new OtpForm($this->totpService, true); if ($formHydrator->populateFromPostAndValidate($formModel, $request)) { $this->redirct('verified'); } return $this->viewRenderer->render( 'enable2faView', [ 'formModel' => $formModel, ] ); }
// Verify TOTP View <?= $form ->post($url) ->csrf($csrf) ->open() ; ?> <?= Field::text($formModel, 'code') ?> <?= Field::submitButton('Verify') ?> <?= $form->close() ?>
OTPForm
final class OtpForm extends FormModel { private string $otpCode = ''; public function __construct( private readonly TotpService $totpService, private readonly bool $allowBackupCode = false ) { } public function getRules(): array { return [ 'otpCode' => [ new Required(), new Regex(($this->allowBackupCode ? '/.+/' : '/\d{3}\s?\d{3}/')), new Callback( callback: function (): Result { $result = new Result(); if (!$this->totpService->verify(str_replace(' ', '', $this->otpCode))) { $result->addError('Invalid Code'); } return $result; }, ), ] ]; } }