yii2tech / authlog
提供身份认证跟踪和暴力破解保护支持
Requires
- yiisoft/yii2: ~2.0.0
This package is auto-updated.
Last update: 2022-01-10 10:41:26 UTC
README
为Yii2的身份认证跟踪扩展
此扩展提供了身份认证日志和跟踪机制,可用于“暴力破解”攻击保护。
有关许可证信息,请参阅LICENSE文件。
安装
安装此扩展的首选方式是通过composer。
运行以下命令:
php composer.phar require --prefer-dist yii2tech/authlog
或添加以下内容到您的composer.json文件的require部分:
"yii2tech/authlog": "*"
使用方法
此扩展提供了身份认证日志和跟踪机制,可用于“暴力破解”攻击保护。
扩展通过ActiveRecord实体实现认证尝试日志。此类实体的数据库迁移可以如下所示:
$this->createTable('UserAuthLog', [ 'id' => $this->primaryKey(), 'userId' => $this->integer(), 'date' => $this->integer(), 'cookieBased' => $this->boolean(), 'duration' => $this->integer(), 'error' => $this->string(), 'ip' => $this->string(), 'host' => $this->string(), 'url' => $this->string(), 'userAgent' => $this->string(), ]);
实现[[\yii\web\IdentityInterface]]的ActiveRecord模型应声明对此实体的“多对一”关系。日志机制通过[[\yii2tech\authlog\AuthLogIdentityBehavior]]行为提供,该行为也应附加到身份类。例如
use Yii; use yii\db\ActiveRecord; use yii\web\IdentityInterface; use yii2tech\authlog\AuthLogIdentityBehavior; class User extends ActiveRecord implements IdentityInterface { public function behaviors() { return [ 'authLog' => [ 'class' => AuthLogIdentityBehavior::className(), 'authLogRelation' => 'authLogs', 'defaultAuthLogData' => function ($model) { return [ 'ip' => Yii::$app->request->getUserIP(), 'host' => @gethostbyaddr(Yii::$app->request->getUserIP()), 'url' => Yii::$app->request->getAbsoluteUrl(), 'userAgent' => Yii::$app->request->getUserAgent(), ]; }, ], ]; } public function getAuthLogs() { return $this->hasMany(UserAuthLog::className(), ['userId' => 'id']); } // ... }
注意:因为[[\yii2tech\authlog\AuthLogIdentityBehavior]]通过ActiveRecord工作,所以认证日志存储可以是任何实现了ActiveRecord层的,如Redis、MongoDB等。
附加[[\yii2tech\authlog\AuthLogIdentityBehavior]]提供了基本的认证日志和统计方法
logAuth()
写入认证日志条目logAuthError()
写入认证日志错误条目getLastSuccessfulAuthLog()
返回最后一个成功的认证日志条目getPreLastSuccessfulAuthLog()
返回前一个成功的认证日志条目getLastLoginDate()
返回最后一个成功的登录日期getPreLastLoginDate()
返回前一个成功的登录日期hasFailedLoginSequence()
检查是否存在从现在开始的请求长度为失败的登录尝试序列
有关配置和可用方法的详细信息,请参阅[[\yii2tech\authlog\AuthLogIdentityBehavior]]。
请注意,[[\yii2tech\authlog\AuthLogIdentityBehavior]]不会自动记录认证尝试。您需要在适当的位置手动调用日志方法。然而,此扩展提供了其他工具,可以完成这项任务。
自动认证日志
尽管[[\yii2tech\authlog\AuthLogIdentityBehavior]]提供了认证日志的基础,但它不会自动记录任何内容。成功的认证尝试的自动记录通过[[\yii2tech\authlog\AuthLogWebUserBehavior]]行为提供。[[\yii2tech\authlog\AuthLogWebUserBehavior]]应附加到“user”应用程序组件([[\yii\web\User]]的实例)。这可以在应用程序配置中完成
return [ 'components' => [ 'user' => [ 'identityClass' => 'app\models\User', 'loginUrl' => ['site/login'], 'as authLog' => [ 'class' => 'yii2tech\authlog\AuthLogWebUserBehavior' ], ], // ... ], // ... ];
[[\yii2tech\authlog\AuthLogWebUserBehavior]]依赖于具有[[\yii2tech\authlog\AuthLogIdentityBehavior]]身份类的附加,并在通过所有者[[\yii\web\User]]组件进行任何成功的登录时写入认证日志,包括基于cookie的登录。然而,此行为无法记录任何失败的认证尝试,这应该在登录表单等其他地方完成。
记录认证失败
记录认证失败是特定于应用程序使用的认证方法。因此,您需要自行负责其执行。
最常用的认证方法是使用用户名/密码对,这通过登录网页表单进行请求。在这种情况下,认证失败应该记录在输入无效密码的情况下。此扩展提供了[[\yii2tech\authlog\AuthLogLoginFormBehavior]]行为,可以将它附加到登录表单模型上,提供认证失败记录功能。例如
use app\models\User; use yii2tech\authlog\AuthLogLoginFormBehavior; class LoginForm extends Model { public $username; public $password; public $rememberMe = true; public function behaviors() { return [ 'authLog' => [ 'class' => AuthLogLoginFormBehavior::className(), 'findIdentity' => 'findIdentity', ], ]; } public function findIdentity() { return User::findByUsername($this->username); } // ... }
[[\yii2tech\authlog\AuthLogLoginFormBehavior]]在发现身份并存在[[\yii2tech\authlog\AuthLogLoginFormBehavior::$verifyIdentityAttributes]]上的任何错误时,自动记录在所有者验证中的失败认证尝试。
"暴力破解"保护
除了简单的日志记录外,[[\yii2tech\authlog\AuthLogLoginFormBehavior]]还提供了内置的"暴力破解"攻击保护机制,具有2个级别
- 在[[\yii2tech\authlog\AuthLogLoginFormBehavior::$verifyRobotFailedLoginSequence]]序列登录失败后要求机器人验证(CAPTCHA)
- 在[[\yii2tech\authlog\AuthLogLoginFormBehavior::$deactivateFailedLoginSequence]]序列登录失败后禁用身份记录
例如
use app\models\User; use yii2tech\authlog\AuthLogLoginFormBehavior; class LoginForm extends Model { public $username; public $password; public $rememberMe = true; public $verifyCode; public function behaviors() { return [ 'authLog' => [ 'class' => AuthLogLoginFormBehavior::className(), 'findIdentity' => 'findIdentity', 'verifyRobotAttribute' => 'verifyCode', 'deactivateIdentity' => function ($identity) { return $this->updateAttributes(['statusId' => User::STATUS_SUSPENDED]); }, ], ]; } public function rules() { return [ [['username', 'password'], 'required'], ['rememberMe', 'boolean'], ['password', 'validatePassword'], ['verifyCode', 'safe'], ]; } public function findIdentity() { return User::findByUsername($this->username); } // ... }
机器人验证需要在视图层进行额外处理,应该在必要时才渲染CAPTCHA
<?php $form = ActiveForm::begin(['id' => 'login-form']); ?> <?= $form->field($model, 'username') ?> <?= $form->field($model, 'password')->passwordInput() ?> <?php if (Yii::$app->user->enableAutoLogin) : ?> <?= $form->field($model, 'rememberMe')->checkbox() ?> <?php endif; ?> <?php if ($model->isVerifyRobotRequired) : ?> <?= $form->field($model, 'verifyCode')->widget(Captcha::className(), [ 'template' => '{image}{input}', ]) ?> <?php endif; ?> <div class="form-group"> <?= Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?> </div> <?php ActiveForm::end(); ?>
注意!虽然[[\yii2tech\authlog\AuthLogLoginFormBehavior]]旨在覆盖最常见的网页登录表单工作流程,但不要局限于它。准备创建自己的功能实现。
垃圾回收
记录系统中每个用户的每次认证尝试可能会在没有太多目的的情况下消耗日志存储(数据库)过多的空间。通常,从用户注册开始,没有必要存储单个用户的全部认证尝试。因此提供了一个内置的垃圾回收机制。
使用[[\yii2tech\authlog\AuthLogIdentityBehavior]]在写入日志时自动触发垃圾回收。您可以设置gcProbability
和gcLimit
来控制此过程或直接调用gcAuthLogs()
。