Dcat-admin实现一个账号只能同时在线一次

Laravel框架
569
0
0
2022-04-09
标签   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驱动

Dcat-admin实现一个账号只能同时在线一次