AuthController.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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. /**
  21. * Jwt受众.
  22. *
  23. * @var string
  24. */
  25. private $jwtAud = 'manage-users';
  26. /**
  27. * 属性描述.
  28. *
  29. * @var ManagerLogRepository
  30. */
  31. protected $logRepo = null;
  32. /**
  33. * 管理员登陆.
  34. * @param ValidatorFactoryInterface $validatorFactory
  35. * @param ManagerRepository $managerRepository
  36. * @param AuthService $authService
  37. * @return mixed
  38. * @throws \Psr\SimpleCache\InvalidArgumentException
  39. */
  40. public function login(
  41. ValidatorFactoryInterface $validatorFactory,
  42. ManagerRepository $managerRepository,
  43. AuthService $authService
  44. ) {
  45. $inputData = $this->getJsonData();
  46. $rules = [
  47. 'account' => 'required|max:120',
  48. 'password' => 'required|max:64',
  49. 'verify' => 'nullable|max:12',
  50. ];
  51. $validator = $validatorFactory->make($inputData, $rules);
  52. if ($validator->fails()) {
  53. // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
  54. return json_fail($validator->errors()->first());
  55. }
  56. // 查询字段.
  57. $columns = [
  58. 'id', 'manager_id', 'username', 'nick', 'role_id', 'password', 'salt', 'locked_at',
  59. ];
  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 = [
  94. 'manager_id' => $manager->manager_id,
  95. 'username' => $manager->username,
  96. 'nick' => $manager->nick,
  97. 'subject' => mb_strcut($logSubject, 0, 700),
  98. 'module' => $module,
  99. 'action' => $action,
  100. 'svalue' => !empty($logSvalue) ? $logSvalue : '',
  101. 'db_data' => [],
  102. ];
  103. $this->getLogRepo()->createOne($inputs);
  104. $tokenInfo = $authService->createSingleJwt($manager->manager_id, $manager->role_id);
  105. $data = [
  106. 'token' => $tokenInfo['token'],
  107. 'expired_at' => $tokenInfo['expired_at'],
  108. 'manager_id' => $manager->manager_id,
  109. ];
  110. return json_success($data);
  111. }
  112. public function logout()
  113. {
  114. }
  115. /**
  116. * 刷新Token并返回token.
  117. * @param ValidatorFactoryInterface $validatorFactory
  118. * @param JwtRepository $jwtRepository
  119. * @param \Modules\Manage\Services\AuthService $authService
  120. * @return mixed
  121. * @throws \Psr\SimpleCache\InvalidArgumentException
  122. */
  123. public function refreshToken(
  124. ValidatorFactoryInterface $validatorFactory,
  125. JwtRepository $jwtRepository,
  126. AuthService $authService
  127. ) {
  128. $inputData = $this->getJsonData();
  129. $rules = [
  130. 'manager_id' => 'required',
  131. 'old_token' => 'required',
  132. ];
  133. $validator = $validatorFactory->make($inputData, $rules);
  134. if ($validator->fails()) {
  135. // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
  136. return json_fail($validator->errors()->first());
  137. }
  138. $validateResult = $jwtRepository->validateToken($inputData['old_token'], $this->jwtAud);
  139. $tokenObj = $validateResult['token_obj'];
  140. $manager = new \stdClass();
  141. $managerId = $tokenObj->getClaim('manager_id');
  142. $roleId = $tokenObj->getClaim('role_id');
  143. // 检查入参设备信息是否有效.
  144. if ($managerId!= $inputData['manager_id']) {
  145. $logSubject = '后台登陆刷新token失败;原因:入参manager_id和token中的manager_id不一致;入参:manager_id['. $inputData['manager_id'] .']';
  146. $logSvalue = '';
  147. $logDbData = [];
  148. $this->log($logSubject, $logSvalue, $logDbData);
  149. return json_fail('无效数据匹配.');
  150. }
  151. if (!$validateResult['is_valid'] && $validateResult['is_expired']) {
  152. return json_fail('旧Token无效');
  153. }
  154. $tokenInfo = $authService->createSingleJwt($managerId, $roleId);
  155. $data = [
  156. 'token' => $tokenInfo['token'],
  157. 'expired_at' => $tokenInfo['expired_at'],
  158. ];
  159. return json_success($data);
  160. }
  161. /**
  162. * 记录操作日志.
  163. * @param string $subject 主题.
  164. * @param string $svalue 关联数据.
  165. * @param array $dbData 此数组数据结构一定要是["after_items" => [0, 1, 2], "before_items" => [0, 1, 2]], after_items,before_items 是一个二维码数组.
  166. * @return bool
  167. */
  168. protected function log(string $subject, $svalue = '', $dbData = [])
  169. {
  170. list($module, $action) = $this->getModuleAndAction();
  171. $inputs = [
  172. 'manager_id' => '',
  173. 'username' => '',
  174. 'nick' => '匿名',
  175. 'subject' => mb_strcut((string)$subject, 0, 700),
  176. 'module' => $module,
  177. 'action' => $action,
  178. 'svalue' => !empty($svalue) ? mb_strcut((string)$svalue, 0, 700) : '',
  179. 'db_data' => $dbData,
  180. ];
  181. $this->getLogRepo()->createOne($inputs);
  182. return true;
  183. }
  184. /**
  185. * 获取日志仓库.
  186. * @return ManagerLogRepository|null
  187. */
  188. protected function getLogRepo()
  189. {
  190. if (empty($this->logRepo)) {
  191. $this->logRepo = make(ManagerLogRepository::class);
  192. }
  193. return $this->logRepo;
  194. }
  195. }