diff --git a/controllers/UserController.php b/controllers/UserController.php index 5b59527..6caf0ff 100644 --- a/controllers/UserController.php +++ b/controllers/UserController.php @@ -183,18 +183,40 @@ class UserController extends Controller if ($model->load(Yii::$app->request->post())) { // 验证二步验证代码 - $otp = TOTP::createFromSecret($user->otp_secret); - if ($otp->verify($model->totp_input)) { - $user->last_login = date('Y-m-d H:i:s'); - $user->last_login_ip = Yii::$app->request->userIP; - if (!$user->save(false)) { - Yii::$app->session->setFlash('error', '登陆成功,但出现了内部错误'); + if(!is_null($model->totp_input)){ + $otp = TOTP::createFromSecret($user->otp_secret); + if ($otp->verify($model->totp_input)) { + $user->last_login = date('Y-m-d H:i:s'); + $user->last_login_ip = Yii::$app->request->userIP; + if (!$user->save(false)) { + Yii::$app->session->setFlash('error', '登陆成功,但出现了内部错误'); + } + Yii::$app->user->login($user, $model->rememberMe ? 3600 * 24 * 30 : 0); + Yii::$app->session->remove('login_verification'); + return $this->goHome(); + } else { + Yii::$app->session->setFlash('error', '二步验证代码错误'); } - Yii::$app->user->login($user, $model->rememberMe ? 3600 * 24 * 30 : 0); - Yii::$app->session->remove('login_verification'); - return $this->goHome(); - } else { - Yii::$app->session->setFlash('error', '二步验证代码错误'); + }elseif (!is_null($model->recoveryCode_input)) { + $recoveryCodes = explode(',', $user->recovery_codes); + if (in_array($model->recoveryCode_input, $recoveryCodes)) { + //remove the used recovery code + $recoveryCodes = array_diff($recoveryCodes, [$model->recoveryCode_input]); + $user->recovery_codes = implode(',', $recoveryCodes); + $user->last_login = date('Y-m-d H:i:s'); + $user->last_login_ip = Yii::$app->request->userIP; + if (!$user->save(false)) { + Yii::$app->session->setFlash('error', '登陆成功,但出现了内部错误'); + } + Yii::$app->session->setFlash('success', '登陆成功,但请注意已经使用的恢复代码已失效'); + Yii::$app->user->login($user, $model->rememberMe ? 3600 * 24 * 30 : 0); + Yii::$app->session->remove('login_verification'); + return $this->goHome(); + } else { + Yii::$app->session->setFlash('error', '恢复代码错误'); + } + }else{ + Yii::$app->session->setFlash('error', '请输入二步验证代码或恢复代码'); } } diff --git a/models/User.php b/models/User.php index 0918f5a..54ad145 100644 --- a/models/User.php +++ b/models/User.php @@ -42,6 +42,7 @@ class User extends ActiveRecord implements IdentityInterface public $newPassword; // 新密码 修改密码用 public $newPasswordRepeat; // 重复新密码 修改密码用 public $totp_input; // otp用户输入值 + public $recoveryCode_input; // 恢复代码用户输入 /** * {@inheritdoc} @@ -59,7 +60,7 @@ class User extends ActiveRecord implements IdentityInterface return [ [['status', 'is_encryption_enabled', 'is_otp_enabled','dark_mode'], 'integer'], [['created_at', 'last_login'], 'safe'], - [['bio', 'totp_input'], 'string'], + [['bio', 'totp_input','recoveryCode_input'], 'string'], [['encryption_key', 'otp_secret', 'recovery_codes'], 'string', 'max' => 255], [['last_login_ip'], 'string', 'max' => 45], [['username', 'password'], 'required', 'on' => 'login'], diff --git a/views/user/verifyTwoFactor.php b/views/user/verifyTwoFactor.php index 005fc8f..6e9337c 100644 --- a/views/user/verifyTwoFactor.php +++ b/views/user/verifyTwoFactor.php @@ -23,6 +23,13 @@ $this->params['breadcrumbs'][] = $this->title; 'btn btn-primary']) ?> +
+ + field($model, 'recoveryCode_input')->textInput()->label('丢失所有验证设备? 使用恢复代码') ?> +
+ 'btn btn-primary']) ?> +
+