Dcat-admin实现一个账号只能同时在线一次
具体思路很简单-当用户登录删除上次登录的session并记录现在登录的session id
文档上所写 我们可以重写父类AuthController
的方法
namespace App\Admin\Controllers;
use Dcat\Admin\Controllers\AuthController as BaseAuthController;
class AuthController extends BaseAuthController
{
// 自定义登录view模板
protected $view = 'admin.login';
// 重写你的登录页面逻辑
public function getLogin(Content $content)
{
...
}
...
}
查看继承的父类BaseAuthController
,可以看到验证登录的方法
/**
* Handle a login request.
*
* @param Request $request
*
* @return mixed
*/
public function postLogin(Request $request)
{
$credentials = $request->only([$this->username(), 'password']);
$remember = (bool) $request->input('remember', false);
/** @var \Illuminate\Validation\Validator $validator */
$validator = Validator::make($credentials, [
$this->username() => 'required',
'password' => 'required',
]);
if ($validator->fails()) {
return $this->validationErrorsResponse($validator);
}
if ($this->guard()->attempt($credentials, $remember)) {
//验证成功后执行响应成功
return $this->sendLoginResponse($request);
}
return $this->validationErrorsResponse([
$this->username() => $this->getFailedLoginMessage(),
]);
}
验证登录成功后执行sendLoginResponse
方法并会生成一个session令牌
/**
* Send the response after the user was authenticated.
*
* @param \Illuminate\Http\Request $request
*
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function sendLoginResponse(Request $request)
{
$request->session()->regenerate();
return $this->redirectToIntended(
$this->redirectPath(),
trans('admin.login_successful')
);
}
在新创建的子类里面重写该方法
/**
* Send the response after the user was authenticated.
*
* @param \Illuminate\Http\Request $request
*
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function sendLoginResponse(Request $request)
{
//删除旧的会话信息
$this->delSessionForRedis();
$request->session()->regenerate();
//存储新的会话信息
$this->setSessionForRedis();
return $this->redirectToIntended(
$this->redirectPath(),
trans('admin.login_successful')
);
}
/**
* 将会话id缓存入redis
*/
private function setSessionForRedis()
{
Redis::set('session_id_'.auth()->id(),'_database__cache:'.session()->getId());
}
/**
* 清理旧会话
*/
private function delSessionForRedis()
{
$key = Redis::get('session_id_'.auth()->id());
if($key){
$key = '_'.trim($key,"_database_");
Redis::del($key);
}
}
实现了两步删除上一次登录的session、记录当前的session会话id 最后在.env
中将SESSION_DRIVER
更改为redis
驱动
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: