这个ThrottlesLogins trait位于Illuminate\Foundation\Auth\ThrottlesLogins,你可以在5.2自带的Auth/AuthController之下看到它的的用例。
它的原理是在缓存里写入一个key来验证当前用户以前当前ip是否有过多的登录失败操作。
如果你不想用make:auth来自动生成登录表单,想自己进行验证,那么这篇文章也许对你有用。
假如我们要做一个管理员的登录,有一个AdminController, Admin模型和其对应的数据表admins。你需要将Admin模型的扩展对象改为Authenticatable来使用Auth门面。(这里省去一些在config/auth.php下设置guard的步骤)
<?php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Admin extends Authenticatable
{
protected $fillable = [
'name',
'password'
];
}
然后我们就可以到AdminController来写验证逻辑了:
<?php
namespace App\Http\Controllers;
use App\Admin;
use Illuminate\Http\Request;
use App\Http\Requests;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Session;
class AdminController extends Controller
{
use ThrottlesLogins;
public $username = 'name'; //ThrottleLogins的重定向以及getThrottleKey方法需要用到
public function __construct()
{
$this->middleware('auth:admin', ['except' => ['index', 'auth']]);
}
public function index()
{
return view('admin.index');
}
public function loginUsername()
{
return property_exists($this, 'username') ? $this->username : 'email';
}
protected function getThrottleKey(Request $request)
{
return mb_strtolower('admin.'.$request->input($this->loginUsername())).'|'.$request->ip();
}
public function auth(Request $request)
{
if ($this->hasTooManyLoginAttempts($request)) {
return $this->sendLockoutResponse($request);
} else {
$this->validate($request, [
'name' => 'required',
'password' => 'required'
], [
'name.required' => '请填写用户名',
'password.required' => '请填写密码',
]);
if (Auth::Guard('admin')->attempt(['name' => $request->name, 'password' => $request->password])) {
return 'OK';
} else {
$this->incrementLoginAttempts($request);
Session::flash('login_error', '用户名或密码错误');
return Redirect::back()->withInput();
}
}
}
}
我们来看看,首先是引用进了
use Illuminate\Foundation\Auth\ThrottlesLogins;
然后在类里使用它
use ThrottlesLogins;
接下来你会看到一个$username属性,这个在trait里是用来取得缓存key,以及重定向之后widhInput需要保留的表单项。
我们需要自己在类里写一个loginUsername()方法,因为trait里用它来取得登录表单里的『用户』这一项。
public function loginUsername()
{
return property_exists($this, 'username') ? $this->username : 'email';
}
我们直接在类里重写了trait里getThrottleKey的方法,在key的最前面加入了admin这一串字符
protected function getThrottleKey(Request $request)
{
return mb_strtolower('admin'.$request->input($this->loginUsername())).'|'.$request->ip();
}
最后我们就可以开始进行验证了。
首先需要看看当前用户是不是有过多的登录
if ($this->hasTooManyLoginAttempts($request)){
...
}
如果没有的话就开始验证,并且在验证失败之后让当前验证错误次数+1。
laravel自带的这个trait默认是一分钟内可以失败五次,失败五次之后会在缓存里写入时间为1分钟的名称为"laravel|key:lockout"的key。
就是说接下来的一分钟之内是无法进行登录的。
if (Auth::Guard('admin')->attempt(['name' => $request->name, 'password' => $request->password])) {
return 'OK';
} else {
$this->incrementLoginAttempts($request);
Session::flash('login_error', '用户名或密码错误');
return Redirect::back()->withInput();
}
2 条评论
alert("XSS");
好低級哦 你退群吧