Modules_Manage_Controllers_AuthController.proxy.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. <?php
  2. /**
  3. * 管理员认证.
  4. *
  5. * @author jim <jim458734573@gmail.com>
  6. * @date 2020-01-22 20:24:20
  7. */
  8. declare (strict_types=1);
  9. namespace Modules\Manage\Controllers;
  10. use App\Controller\CoreController;
  11. use App\Model\ManagerModel;
  12. use App\Repositories\ManagerLogRepository;
  13. use App\Repositories\ManagerRepository;
  14. use App\Repositories\Utils\AccessControllerListsRepository;
  15. use App\Repositories\Utils\JwtRepository;
  16. use Hyperf\Validation\Contract\ValidatorFactoryInterface;
  17. use Modules\Manage\Services\AuthService;
  18. class AuthController extends CoreController
  19. {
  20. use \Hyperf\Di\Aop\ProxyTrait;
  21. use \Hyperf\Di\Aop\PropertyHandlerTrait;
  22. function __construct()
  23. {
  24. if (method_exists(parent::class, '__construct')) {
  25. parent::__construct(...func_get_args());
  26. }
  27. $this->__handlePropertyHandler(__CLASS__);
  28. }
  29. /**
  30. * Jwt受众.
  31. *
  32. * @var string
  33. */
  34. private $jwtAud = 'manage-users';
  35. /**
  36. * 属性描述.
  37. *
  38. * @var ManagerLogRepository
  39. */
  40. protected $logRepo = null;
  41. /**
  42. * 管理员登陆.
  43. * @param ValidatorFactoryInterface $validatorFactory
  44. * @param ManagerRepository $managerRepository
  45. * @param AuthService $authService
  46. * @return mixed
  47. * @throws \Psr\SimpleCache\InvalidArgumentException
  48. */
  49. public function login(ValidatorFactoryInterface $validatorFactory, ManagerRepository $managerRepository, AuthService $authService)
  50. {
  51. $inputData = $this->getJsonData();
  52. $rules = ['account' => 'required|max:120', 'password' => 'required|max:64', 'verify' => 'nullable|max:12'];
  53. $validator = $validatorFactory->make($inputData, $rules);
  54. if ($validator->fails()) {
  55. // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
  56. return json_fail($validator->errors()->first());
  57. }
  58. // 查询字段.
  59. $columns = ['id', 'manager_id', 'username', 'nick', 'role_id', 'password', 'salt', 'locked_at'];
  60. // 条件.
  61. $conditions = ['username' => $inputData['account']];
  62. $managers = make(ManagerRepository::class)->findWhere($conditions, $columns);
  63. // 先判断是否存在用户.
  64. if (!$managers->count()) {
  65. $logSubject = '后台登陆获取token失败;原因:无此账号;入参:account[' . $inputData['account'] . '];密码:[' . pass_encode($inputData['password']) . ']';
  66. $logSvalue = '';
  67. $logDbData = [];
  68. $this->log($logSubject, $logSvalue, $logDbData);
  69. // 给一个不容易分析的错误信息给前台.
  70. return json_fail('账号或者密码错误.');
  71. }
  72. // 取第一个用户.
  73. $manager = $managers->first();
  74. $md5password = make(ManagerRepository::class)->generatePassword($inputData['password'], $manager->salt);
  75. var_dump($md5password);
  76. if ($manager->password !== $md5password) {
  77. $logSubject = '后台登陆获取token失败;原因:密码错误;入参:account[' . $inputData['account'] . '];密码:[' . pass_encode($inputData['password']) . ']';
  78. $logSvalue = '';
  79. $logDbData = [];
  80. $this->log($logSubject, $logSvalue, $logDbData);
  81. return json_fail('账号或者密码错误.');
  82. }
  83. if (!empty($manager->locked_at)) {
  84. $logSubject = '后台登陆获取token失败;原因:被锁定;入参:account[' . $inputData['account'] . '];密码:[' . pass_encode($inputData['password']) . ']';
  85. $logSvalue = '';
  86. $logDbData = [];
  87. $this->log($logSubject, $logSvalue, $logDbData);
  88. return json_fail('您已经被锁定,无法登陆.');
  89. }
  90. $logSubject = '后台登录成功';
  91. $logSvalue = $manager->manager_id;
  92. list($module, $action) = $this->getModuleAndAction();
  93. $inputs = ['manager_id' => $manager->manager_id, 'username' => $manager->username, 'nick' => $manager->nick, 'subject' => mb_strcut($logSubject, 0, 700), 'module' => $module, 'action' => $action, 'svalue' => !empty($logSvalue) ? $logSvalue : '', 'db_data' => []];
  94. $this->getLogRepo()->createOne($inputs);
  95. $tokenInfo = $authService->createSingleJwt($manager->manager_id, $manager->role_id);
  96. $data = ['token' => $tokenInfo['token'], 'expired_at' => $tokenInfo['expired_at'], 'manager_id' => $manager->manager_id];
  97. return json_success($data);
  98. }
  99. public function logout()
  100. {
  101. }
  102. /**
  103. * 刷新Token并返回token.
  104. * @param ValidatorFactoryInterface $validatorFactory
  105. * @param JwtRepository $jwtRepository
  106. * @param \Modules\Manage\Services\AuthService $authService
  107. * @return mixed
  108. * @throws \Psr\SimpleCache\InvalidArgumentException
  109. */
  110. public function refreshToken(ValidatorFactoryInterface $validatorFactory, JwtRepository $jwtRepository, AuthService $authService)
  111. {
  112. $inputData = $this->getJsonData();
  113. $rules = ['manager_id' => 'required', 'old_token' => 'required'];
  114. $validator = $validatorFactory->make($inputData, $rules);
  115. if ($validator->fails()) {
  116. // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
  117. return json_fail($validator->errors()->first());
  118. }
  119. $validateResult = $jwtRepository->validateToken($inputData['old_token'], $this->jwtAud);
  120. $tokenObj = $validateResult['token_obj'];
  121. $manager = new \stdClass();
  122. $managerId = $tokenObj->getClaim('manager_id');
  123. $roleId = $tokenObj->getClaim('role_id');
  124. // 检查入参设备信息是否有效.
  125. if ($managerId != $inputData['manager_id']) {
  126. $logSubject = '后台登陆刷新token失败;原因:入参manager_id和token中的manager_id不一致;入参:manager_id[' . $inputData['manager_id'] . ']';
  127. $logSvalue = '';
  128. $logDbData = [];
  129. $this->log($logSubject, $logSvalue, $logDbData);
  130. return json_fail('无效数据匹配.');
  131. }
  132. if (!$validateResult['is_valid'] && $validateResult['is_expired']) {
  133. return json_fail('旧Token无效');
  134. }
  135. $tokenInfo = $authService->createSingleJwt($managerId, $roleId);
  136. $data = ['token' => $tokenInfo['token'], 'expired_at' => $tokenInfo['expired_at']];
  137. return json_success($data);
  138. }
  139. /**
  140. * 记录操作日志.
  141. * @param string $subject 主题.
  142. * @param string $svalue 关联数据.
  143. * @param array $dbData 此数组数据结构一定要是["after_items" => [0, 1, 2], "before_items" => [0, 1, 2]], after_items,before_items 是一个二维码数组.
  144. * @return bool
  145. */
  146. protected function log(string $subject, $svalue = '', $dbData = [])
  147. {
  148. list($module, $action) = $this->getModuleAndAction();
  149. $inputs = ['manager_id' => '', '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];
  150. $this->getLogRepo()->createOne($inputs);
  151. return true;
  152. }
  153. /**
  154. * 获取日志仓库.
  155. * @return ManagerLogRepository|null
  156. */
  157. protected function getLogRepo()
  158. {
  159. if (empty($this->logRepo)) {
  160. $this->logRepo = make(ManagerLogRepository::class);
  161. }
  162. return $this->logRepo;
  163. }
  164. }