From 63bc49d63edda9e381910b4f70341bf6819c2cc5 Mon Sep 17 00:00:00 2001 From: Chenx221 Date: Wed, 6 Mar 2024 20:14:47 +0800 Subject: [PATCH] =?UTF-8?q?totp=E5=89=8D=E7=AB=AF=E8=AE=BE=E8=AE=A1(1/2)?= =?UTF-8?q?=20=E5=90=8E=E7=AB=AF=E5=BF=AB=E4=BA=86=EF=BC=8C=E5=88=AB?= =?UTF-8?q?=E6=80=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controllers/UserController.php | 31 +++++++++++------- models/User.php | 6 +++- views/user/info.php | 59 +++++++++++++++++++++++++++++++--- 3 files changed, 79 insertions(+), 17 deletions(-) diff --git a/controllers/UserController.php b/controllers/UserController.php index d27f97a..8029221 100644 --- a/controllers/UserController.php +++ b/controllers/UserController.php @@ -354,21 +354,28 @@ class UserController extends Controller return $this->redirect(['user/info', 'focus' => 'password']); } - /** - * @return string - */ - public function actionSetupTwoFactor(): string + public function actionSetupTwoFactor() { - $user = Yii::$app->user->identity; - $totp = TOTP::create(); - $user->otp_secret = $totp->getSecret(); - $user->is_otp_enabled = true; - $user->save(false); + // ...其他代码... - $otpauth = $totp->getProvisioningUri($user->username); - $qrCodeUrl = 'https://api.qrserver.com/v1/create-qr-code/?data=' . urlencode($otpauth); + // 生成恢复代码 + $recoveryCodes = $this->generateRecoveryCodes(); - return $this->render('setup-two-factor', ['qrCodeUrl' => $qrCodeUrl]); + // 保存恢复代码到数据库或其他安全的地方 + + // 显示恢复代码给用户 + Yii::$app->session->setFlash('success', '二步验证已启用。您的恢复代码是:' . implode(', ', $recoveryCodes)); + + // ...其他代码... + } + + private function generateRecoveryCodes($length = 10, $numCodes = 10) + { + $codes = []; + for ($i = 0; $i < $numCodes; $i++) { + $codes[] = Yii::$app->security->generateRandomString($length); + } + return $codes; } } diff --git a/models/User.php b/models/User.php index dfc10dc..b1fadd6 100644 --- a/models/User.php +++ b/models/User.php @@ -27,6 +27,7 @@ use yii\web\IdentityInterface; * @property int|null $is_encryption_enabled 启用加密 * @property int|null $is_otp_enabled 启用otp * @property int|null $storage_limit 存储容量限制,MB + * @property string|null $recovery_codes OTP恢复代码 * * @property CollectionTasks[] $collectionTasks * @property Share[] $shares @@ -39,6 +40,7 @@ class User extends ActiveRecord implements IdentityInterface public $oldPassword; // 旧密码 修改密码用 public $newPassword; // 新密码 修改密码用 public $newPasswordRepeat; // 重复新密码 修改密码用 + public $totp_input; // otp用户输入值 /** * {@inheritdoc} @@ -57,7 +59,7 @@ class User extends ActiveRecord implements IdentityInterface [['status', 'is_encryption_enabled', 'is_otp_enabled'], 'integer'], [['created_at', 'last_login'], 'safe'], [['bio'], 'string'], - [['encryption_key', 'otp_secret'], 'string', 'max' => 255], + [['encryption_key', 'otp_secret','recovery_codes'], 'string', 'max' => 255], [['last_login_ip'], 'string', 'max' => 45], [['username', 'password'], 'required', 'on' => 'login'], [['username', 'password', 'email', 'password2'], 'required', 'on' => 'register'], @@ -112,6 +114,8 @@ class User extends ActiveRecord implements IdentityInterface 'is_encryption_enabled' => 'Is Encryption Enabled', 'is_otp_enabled' => 'Is Otp Enabled', 'storage_limit' => 'Storage Limit', + 'recovery_codes' => 'Recovery Codes', + ]; } diff --git a/views/user/info.php b/views/user/info.php index cf03de0..4c14526 100644 --- a/views/user/info.php +++ b/views/user/info.php @@ -12,6 +12,7 @@ /* @var $totp_url string */ use app\assets\FontAwesomeAsset; +use app\models\User; use app\utils\FileSizeHelper; use app\utils\IPLocation; use Endroid\QrCode\Color\Color; @@ -44,7 +45,7 @@ $vaultUsedPercent = $is_unlimited ? 0 : round($vaultUsedSpace / ($storageLimit * $totalUsedPercent = min(($usedPercent + $vaultUsedPercent), 100); //总已用百分比 // QR-CODE -if(!is_null($totp_secret)){ +if (!is_null($totp_secret)) { $writer = new PngWriter(); $qrCode = QrCode::create($totp_url) ->setEncoding(new Encoding('UTF-8')) @@ -56,6 +57,9 @@ if(!is_null($totp_secret)){ ->setBackgroundColor(new Color(255, 255, 255)); $result = $writer->write($qrCode); } + +// totp +$user = new User(); ?>
@@ -235,11 +239,13 @@ if(!is_null($totp_secret)){
- - + +
- qrcode
  • @@ -307,6 +313,51 @@ echo '
  • '; echo Html::endForm(); +Modal::end(); + +Modal::begin([ + 'title' => '

    需要进一步操作以启用二步验证

    ', + 'id' => 'totpSetupModal', + 'size' => 'model-xl', +]); +/*qrcode*/ +?> +
    +
    + QR Code +
    +
    +

    使用兼容TOTP的应用程序扫描左侧二维码以添加二步验证

    +

    推荐以下二步验证器::

    + +
    + + + +
    + ['user/actionSetupTwoFactor'], + 'method' => 'post' + ]); ?> + + $totp_secret]) ?> + field($user, 'totp_input')->textInput()->label('最后一步! 输入TOTP应用程序上显示的密码以启用二步验证') ?> + 'btn btn-primary']) ?> + + +
    +
    +registerJsFile('@web/js/user-info.js', ['depends' => [JqueryAsset::class], 'position' => View::POS_END]); ?> \ No newline at end of file