一、登录接口调整
在根目录下app文件夹下controller文件夹下common文件夹下Login.php文件中,修改doLogin接口,代码如下:
//登录
public function doLogin(){
$param = $this->request->param();
$validate = new \app\validate\common\Login;
$result = $validate->check($param);//参数验证
if (!$result) return err($validate->getError());
//验证码的正确性
if (!app()->make(\Other\Captcha::class)->check($param['captcha_code'])) return err('验证码错误');
if (time() + 5 < strtotime($param['login_time'])) return err('非法登录');
$resData = Admin::dataFind(['email' => trim($param['username'])], 'id,realname,password,ip,status', true);
//用户信息的正确性
if (empty($resData) && empty($resData['id'])) return err('用户不存在');
if ($resData['status'] !== 1) return err('该账号已被禁用');
$systemParam = SystemModel::dataFind(['id' => 1],'security_password,platform_token_expira');
if ($resData['password'] !== sha1($param['password'] . $systemParam['security_password'])) return err('账号对应的密码错误');
$loginIp = $this->request->header('x-real-ip');
if(!empty($resData['ip'])){
if($resData['ip'] != $loginIp)return err('禁止访问,不在IP白名单中');
}
//写入Token日志
$data['token_type'] = 1;
$data['menu_name'] = 'CommonLoginDoLogin';
$data['admin_id'] = $resData['id'];
$data['random_number'] = alnum();
$data['client_id'] = '';
$data['login_ip'] = $loginIp;
$data['create_time'] = date('Y-m-d',strtotime($param['login_time']));
$data['login_time'] = $param['login_time'];
$data['expire_time'] = strtotime($param['login_time']) + $systemParam['platform_token_expira'];
$token = $data['admin_id'] . $data['random_number'];
$data['token'] = sha1(sha1($token) . strtotime($data['login_time']));
TokenModel::save($data,[]);
//加入跨站攻击验证队列
Redis::select(config('cache.stores.redis.token_db'))->setex('token_' . $data['token'],$systemParam['platform_token_expira'],$resData['id']);
Redis::select(config('cache.stores.redis.token_db'))->setex('token_' . $resData['id'],$systemParam['platform_token_expira'],Encrypt::encryptRsa($data['token']));
Redis::select(config('cache.stores.redis.data_db_api'))->set($token,$loginIp);
/*$emailSender = new EmailSender();
$emailSender::send($param['username'],'登录系统',$resData['realname'].'于'.$param['login_time'].'登录系统');*/
return succ('登录成功',Encrypt::encryptRsa($token));
}
二、调整控制台接口
1、读取数据
在根目录下app文件夹下model文件夹下common文件夹下Token.php文件中,修改setToken静态方法,代码如下:
//修改token整个状态
public static function setToken($token, $attack, $clientIp){
$data['admin_id'] = 0;
$data['username'] = '';
$data['avatar'] = '';
$data['realname'] = '';
$data['email'] = '';
$data['ip'] = '';
$data['department_id'] = 0;
$data['grade_id'] = 0;
$data['role_id'] = 0;
$data['random_number'] = '';
$data['client_id'] = '';
$data['login_ip'] = '';
$redisToken = Redis::select(config('cache.stores.redis.token_db'))->get('token_'.$token);
if(empty($redisToken))return array('status' => false, 'info' => 'token已经过期咯,请重新登录!', 'data' => $data);
//获取系统配置的过期时间
$systemParam = SystemModel::dataFind(['id' => 1],'platform_token_expira');
//验证是否跨站攻击
$attackToken = Redis::select(config('cache.stores.redis.token_db'))->get('token_' . $redisToken);
if(!empty($attackToken)){
if ($attackToken === $attack){
//如果传过来加密后的token与Redis里面记录的一样,就禁止访问、延长过期时间并加入黑名单
Redis::select(config('cache.stores.redis.token_db'))->expire('token_'.$token, $systemParam['platform_token_expira']);
//加入黑名单
//Redis::select(config('cache.stores.redis.default_db'))->sadd('black-list', $clientIp);
//return array('status' => false, 'info' => '跨站攻击', 'data' => $data);
}
}
Redis::select(config('cache.stores.redis.token_db'))->expire('token_'.$token, $systemParam['platform_token_expira']);
Redis::select(config('cache.stores.redis.token_db'))->setex('token_' . $redisToken, $systemParam['platform_token_expira'], $attack);
$resAdminFind = Admin::dataFind(['id' => $redisToken], 'username,avatar,realname,email,ip,department_id,grade_id,role_id,status',true);
if ($resAdminFind['status'] !== 1) return array('status' => false, 'info' => '该用户已被禁用', 'data' => $data);
$resTokenFind = self::dataFind(['token' => $token],'random_number,client_id,login_ip',true);
$data['admin_id'] = $redisToken;
$data['username'] = $resAdminFind['username'];
$data['avatar'] = $resAdminFind['avatar'];
$data['realname'] = $resAdminFind['realname'];
$data['email'] = $resAdminFind['email'];
$data['ip'] = $resAdminFind['ip'];
$data['department_id'] = $resAdminFind['department_id'];
$data['grade_id'] = $resAdminFind['grade_id'];
$data['role_id'] = $resAdminFind['role_id'];
$data['random_number'] = $resTokenFind['random_number'];
$data['client_id'] = $resTokenFind['client_id'];
$data['login_ip'] = $resTokenFind['login_ip'];
return array('status' => true, 'info' => '', 'data' => $data);
}
2、赋值数据
在根目录下app文件夹下controller文件夹下Base.php文件中,修改token验证方法,也就是isLoginAuth方法,代码如下:
//token验证
private function isLoginAuth(){
$headInfo = $this->request->header();
if(!isset($headInfo['authorization']))throw new BaseError('非法操作!');
if(empty($headInfo['authorization']))throw new BaseError('操作异常!');
if(!empty($this->loginIp)){
if($this->loginIp != $headInfo['x-real-ip'])throw new BaseError('危险操作!');
}
$tokenValue = explode('|', Encrypt::decryptRsa($headInfo['authorization']));//解密 --转换token
if(count($tokenValue) != 2)throw new BaseError('登录认证权限错误',50034,200);
$token = sha1(sha1($tokenValue[0]).strtotime($tokenValue[1]));
$res = Token::setToken($token, $headInfo['authorization'], $headInfo['x-real-ip']);
if($res['status'] === false)throw new BaseError($res['info'],50034,200);//赋值错误信息
$this->userId = $res['data']['admin_id'];
$this->avatar = $res['data']['avatar'];
$this->username = $res['data']['username'];
$this->realname = $res['data']['realname'];
$this->email = $res['data']['email'];
$this->ip = $res['data']['ip'];
$this->departmentId = $res['data']['department_id'];
$this->gradeId = $res['data']['grade_id'];
$this->roleId = $res['data']['role_id'];
$this->token = $token;
$this->randomNumber = $res['data']['random_number'];
$this->loginIp = $res['data']['login_ip'];
$this->clientId = $res['data']['client_id'];
}
三、调整操作日志记录
在根目录下app文件夹下controller文件夹下Base.php文件中,修改setToken方法,代码如下:
/**
* 操作日志记录
* User: 龙哥·三年风水
* Date: 2024/12/12
* Time: 17:11
* @ param $tokenType 操作类型
* @ param $menuName 权限名称
*/
protected function setToken($tokenType,$menuName){
$data['token_type'] = $tokenType;
$data['menu_name'] = $menuName;
$data['admin_id'] = $this->userId;
$data['random_number'] = $this->randomNumber;
$data['client_id'] = $this->clientId;
$data['login_ip'] = $this->loginIp;
$data['create_time'] = date('Y-m-d',time());
$data['login_time'] = date('Y-m-d H:i:s',time());
$data['expire_time'] = time();
$data['token'] = $this->token;
Token::save($data,[]);
}
四、修改表结构
在对应的数据库中修改登录者操作日志表,添加两个字段client_id、login_ip。具体代码如下: