getJsonData(); /** * @var Validator $validatorFactory */ $validatorFactory = app('validator'); /** * @var ManagerRepository $managerRepo */ $managerRepo = app(ManagerRepository::class); /** * @var ManageAuthService $authService */ $authService = app(ManageAuthService::class); $rules = [ 'account' => 'required|max:120', 'password' => 'required|max:64', 'verify' => 'nullable|max:12', 'ggcode' => 'nullable|max:10', ]; $validator = $validatorFactory->make($inputData, $rules); if ($validator->fails()) { // 如果有错误(可能是多个信息),这里只取第一个错误信息返回. return json_fail($validator->errors()->first()); } // 查询字段. $columns = [ 'id', 'manager_uid', 'username', 'nick', 'role_id', 'password', 'salt', 'locked_at', 'otp_secret', ]; // 条件. $conditions = ['username' => $inputData['account']]; $managers = $managerRepo->findWhere($conditions, $columns); // 先判断是否存在用户. if ($managers->count() == 0) { $logSubject = '后台登陆获取token失败;原因:无此账号;入参:account['. $inputData['account'] .'];密码:['. pass_encode($inputData['password']) .']'; $logSvalue = ''; $logDbData = []; $this->log($logSubject, $logSvalue, $logDbData); // 给一个不容易分析的错误信息给前台. return json_fail('账号或者密码错误.'); } // 取第一个用户. $manager = $managers->first(); $md5password = $managerRepo->generatePassword($inputData['password'], $manager->salt); if ($manager->password !== $md5password) { $logSubject = '后台登陆获取token失败;原因:密码错误;入参:account['. $inputData['account'] .'];密码:['. pass_encode($inputData['password']) .']'; $logSvalue = ''; $logDbData = []; $this->log($logSubject, $logSvalue, $logDbData); return json_fail('账号或者密码错误.'); } $ggcode = isset($inputData['ggcode']) ? $inputData['ggcode'] : ''; $isOpenOtp = boolval(env('OTP_OPEN', true)); //是否开启谷歌身份码验证功能 if ($isOpenOtp) { if (empty($ggcode)) { return json_fail('请填写身份码.'); } $otp = new Otp(); $otpSecret = !empty($manager->otp_secret) ? $manager->otp_secret : GoogleAuthenticator::generateRandom(); $otpCheckResult = $otp->checkTotp(Encoding::base32DecodeUpper($otpSecret), $ggcode); if (!$otpCheckResult) { $logSubject = '后台登陆获取token失败;原因:OTP错误;入参:account['. $inputData['account'] .'];密码:['. pass_encode($inputData['password']) .'];otp:['. pass_encode($ggcode) .']'; $logSvalue = ''; $logDbData = []; $this->log($logSubject, $logSvalue, $logDbData); return json_fail('身份码不正确'); } } if (!empty($manager->locked_at)) { $logSubject = '后台登陆获取token失败;原因:被锁定;入参:account['. $inputData['account'] .'];密码:['. pass_encode($inputData['password']) .']'; $logSvalue = ''; $logDbData = []; $this->log($logSubject, $logSvalue, $logDbData); return json_fail('您已经被锁定,无法登陆.'); } $logSubject = '后台登录成功'; $logSvalue = $manager->manager_uid; list($module, $action) = $this->getModuleAndAction(); $inputs = [ 'manager_uid' => $manager->manager_uid, 'username' => $manager->username, 'nick' => $manager->nick, 'subject' => mb_strcut($logSubject, 0, 700), 'module' => $module, 'action' => $action, 'svalue' => !empty($logSvalue) ? $logSvalue : '', 'db_data' => [], ]; $this->getLogRepo()->createOne($inputs); $tokenInfo = $authService->createSingleJwt($manager->manager_uid, $manager->role_id); $data = [ 'token' => $tokenInfo['token'], 'expired_at' => $tokenInfo['expired_at'], 'manager_uid' => $manager->manager_uid, ]; return json_success($data); } public function logout() { } /** * 刷新Token并返回token. * @param mixed $validatorFactory * @param JwtRepository $jwtRepository * @param ManageAuthService $authService * @return mixed * @throws \Psr\SimpleCache\InvalidArgumentException */ public function refreshToken() { /** * @var Validator $validatorFactory */ $validatorFactory = app('validator'); /** * @var ManagerRepository $managerRepo */ $managerRepo = app(ManagerRepository::class); /** * @var ManageAuthService $authService */ $authService = app(ManageAuthService::class); /** * @var JwtRepository $jwtRepository */ $jwtRepository = app(JwtRepository::class); $inputData = $this->getJsonData(); $rules = [ 'manager_uid' => 'required', 'old_token' => 'required', ]; $validator = $validatorFactory->make($inputData, $rules); if ($validator->fails()) { // 如果有错误(可能是多个信息),这里只取第一个错误信息返回. return json_fail($validator->errors()->first()); } $validateResult = $jwtRepository->validateToken($inputData['old_token'], $this->jwtAud); if ($validateResult['is_illegal']) { return json_fail('无效数据传入.'); } if (!$validateResult['is_valid']) { return json_fail('旧Token无效.'); } /*if (!$validateResult['is_expired']) { // 旧token没过期 return json_fail('旧token怎么了'); }*/ /** * @var Token $tokenObj */ $tokenObj = $validateResult['token_obj']; $claims = $tokenObj->claims(); $managerUid = $claims->get('manager_uid'); $roleId = $claims->get('role_id'); // 检查入参设备信息是否有效. if ($managerUid != $inputData['manager_uid']) { $logSubject = '后台登陆刷新token失败;原因:入参manager_uid和token中的manager_uid不一致;入参:manager_uid['. $inputData['manager_uid'] .']'; $logSvalue = ''; $logDbData = []; $this->log($logSubject, $logSvalue, $logDbData); return json_fail('无效数据匹配.'); } $tokenInfo = $authService->createSingleJwt($managerUid, $roleId); $data = [ 'token' => $tokenInfo['token'], 'expired_at' => $tokenInfo['expired_at'], ]; return json_success($data); } /** * php ping * @return string */ public function ping() { return 'pong'; } /** * 记录操作日志. * @param string $subject 主题. * @param string $svalue 关联数据. * @param array $dbData 此数组数据结构一定要是["after_items" => [0, 1, 2], "before_items" => [0, 1, 2]], after_items,before_items 是一个二维码数组. * @return bool */ protected function log(string $subject, $svalue = '', $dbData = []) { list($module, $action) = $this->getModuleAndAction(); $inputs = [ 'manager_uid' => '', 'username' => '', 'nick' => '匿名', 'subject' => mb_strcut((string)$subject, 0, 700), 'module' => $module, 'action' => $action, 'svalue' => !empty($svalue) ? mb_strcut((string)$svalue, 0, 700) : '', 'db_data' => $dbData, ]; $this->getLogRepo()->createOne($inputs); return true; } /** * 获取日志仓库. * @return ManagerLogRepository|null */ protected function getLogRepo() { if (empty($this->logRepo)) { $this->logRepo = make(ManagerLogRepository::class); } return $this->logRepo; } }