这里用的登录就是阅读老外自定义登录和注册功能,用的是Laravel8,如果直接用这种上线,不太安全。如果被暴力破解,不断尝试就麻烦了,现在脚本小子太多了,门槛也低,普通人简单学习几天就能上手去恶心别人。这里我自己写了一个思路,不知道和php主流的是不是一样的。反正我写SpringBoot项目就是用的这种思路。
首先建一个users_lock表
其中这个users_email和users表对应,这里没有外键关系,相当于独立的,这里设计得不是很好,但感觉小站点用足够了。
对应的SQL是这样的:
- CREATE TABLE `users_lock` (
- `user_email` varchar(255) NOT NULL,
- `login_num` int(11) DEFAULT 5,
- `last_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
- `lock_time` timestamp NULL DEFAULT NULL,
- PRIMARY KEY (`user_email`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
注册时把这个表填充下,就好了。
关键是登录时,我的逻辑是这样的:
- public function customLogin(Request $request)
- {
- $request->validate([
- 'email' => 'required|email',
- 'password' => 'required|min:6|max:128',
- 'captcha' => 'required|captcha'
- ]);
-
- //验证
- date_default_timezone_set('Asia/Shanghai');
- $userLock = UserLock::find($request['email']);
- if(!$userLock){
-
- return redirect()->back()->withErrors('用户名或密码不正确');
- }
-
- if($userLock['last_time'] < date('Y-m-d H:i:s',strtotime('-5 minute')) && $userLock['login_num'] <= 0){
-
- $userLock['login_num'] = 5;
- $userLock->save();
- }
-
- //锁
- if($userLock['login_num'] <= 0){
-
- return redirect()->back()->withErrors('帐号锁定,解锁时间 ' . $userLock['lock_time']);
- }
-
- $credentials = $request->only('email', 'password');
-
- if (Auth::attempt($credentials)) {
-
- return redirect()->intended('dashboard')
- ->withSuccess('Signed in');
- }
-
- //次数
- $userLock['login_num'] -= 1;
- if($userLock['login_num'] <= 0){
-
- $userLock['lock_time'] = date('Y-m-d H:i:s',strtotime('+5 minute'));
- }
- $userLock->save();
-
- return redirect()->back()->withErrors('用户名或密码错误');
- }
逻辑:
①先检测users_lock中是否有存在此用户,如果有继续,如果没有,就直接返回;
②判断尝试次数是否为0,如果为0,并且last_time,过期(比当前时间-5分钟要小),就把尝试次数,重新设置为5。
(这里是没有办法的办法,如果有条件的朋友,建议用调度线程去弄,每5分钟跑一次,或者直接用数据库的定时器)
③当login_time为0时,说明帐号已经被锁了。
④使用Laravel的Auth去验证用户名密码。
⑤登录次数-5,如果登录次数<=0就锁账户,锁到当前时间+5分钟。
这里UserLock类是这样的:
- <?php
-
-
- namespace App\Models;
-
-
- use Illuminate\Database\Eloquent\Model;
-
- class UserLock extends Model
- {
- protected $table = "users_lock";
-
- protected $primaryKey = 'user_email';
-
- protected $keyType = 'string';
-
- public $timestamps = false;
- }
用起来还可以: