LoginService.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | Niucloud-admin 企业快速开发的saas管理平台
  4. // +----------------------------------------------------------------------
  5. // | 官方网址:https://www.niucloud.com
  6. // +----------------------------------------------------------------------
  7. // | niucloud团队 版权所有 开源版本可自由商用
  8. // +----------------------------------------------------------------------
  9. // | Author: Niucloud Team
  10. // +----------------------------------------------------------------------
  11. namespace app\service\admin\auth;
  12. use app\dict\sys\AppTypeDict;
  13. use app\model\sys\SysUser;
  14. use app\service\admin\captcha\CaptchaService;
  15. use app\service\admin\user\UserRoleService;
  16. use app\service\admin\user\UserService;
  17. use app\service\core\sys\CoreConfigService;
  18. use core\base\BaseAdminService;
  19. use core\exception\AuthException;
  20. use core\util\TokenAuth;
  21. use Throwable;
  22. /**
  23. * 登录服务层
  24. * Class BaseService
  25. * @package app\service
  26. */
  27. class LoginService extends BaseAdminService
  28. {
  29. public function __construct()
  30. {
  31. parent::__construct();
  32. $this->model = new SysUser();
  33. }
  34. /**
  35. * 用户登录
  36. * @param string $username
  37. * @param string $password
  38. * @param string $app_type
  39. * @return array|bool
  40. */
  41. public function login(string $username, string $password, string $app_type)
  42. {
  43. $this->site_id = $this->request->adminSiteId();
  44. if(!array_key_exists($app_type, AppTypeDict::getAppType())) throw new AuthException('APP_TYPE_NOT_EXIST');
  45. $config = (new ConfigService())->getConfig();
  46. switch($app_type){
  47. case AppTypeDict::SITE:
  48. $is_captcha = $config['is_site_captcha'];
  49. break;
  50. case AppTypeDict::ADMIN:
  51. $is_captcha = $config['is_captcha'];
  52. break;
  53. }
  54. if($is_captcha == 1){
  55. (new CaptchaService())->verification();
  56. }
  57. $user_service = new UserService();
  58. $userinfo = $user_service->getUserInfoByUsername($username);
  59. if ($userinfo->isEmpty()) return false;
  60. if (!check_password($password, $userinfo->password)) return false;
  61. $this->request->uid($userinfo->uid);
  62. if($app_type == AppTypeDict::ADMIN){
  63. $default_site_id = $this->request->defaultSiteId();
  64. $userrole = (new UserRoleService())->getUserRole($default_site_id, $userinfo->uid);
  65. if (!empty($userrole)) {
  66. if (!$userrole['status']) throw new AuthException('USER_LOCK');
  67. } else {
  68. $app_type = AppTypeDict::SITE;
  69. }
  70. } else if($app_type == AppTypeDict::SITE){
  71. $site_ids = (new \app\service\admin\home\AuthSiteService())->getSiteIds();
  72. if(empty($site_ids)){
  73. throw new AuthException('SITE_NOT_EXIST');
  74. }else{
  75. $default_site_id = in_array($this->site_id, $site_ids) ? $this->site_id : $site_ids[0];
  76. }
  77. } else {
  78. throw new AuthException('APP_TYPE_NOT_EXIST');
  79. }
  80. //修改用户登录信息
  81. $userinfo->last_time = time();
  82. $userinfo->last_ip = app('request')->ip();
  83. $userinfo->login_count++;
  84. $userinfo->save();
  85. //创建token
  86. $token_info = $this->createToken($userinfo, $app_type);
  87. //查询权限以及菜单
  88. $data = [
  89. 'token' => $token_info['token'],
  90. 'expires_time' => $token_info['params']['exp'],
  91. 'userinfo' => [
  92. 'uid' => $userinfo->uid,
  93. 'username' => $userinfo->username,
  94. ],
  95. 'site_id' => $default_site_id,
  96. 'site_info' => null,
  97. 'userrole' => $app_type == AppTypeDict::ADMIN ? $userrole : []
  98. ];
  99. if ($app_type == AppTypeDict::ADMIN || ($app_type == AppTypeDict::SITE && $data['site_id']) ) {
  100. $this->request->siteId($data['site_id']);
  101. $data['site_info'] = (new AuthSiteService())->getSiteInfo();
  102. }
  103. // 获取站点布局
  104. $layout_config = (new CoreConfigService())->getConfig($data['site_id'], 'SITE_LAYOUT');
  105. $data['layout'] = empty($layout_config) ? 'default' : $layout_config['value']['key'];
  106. return $data;
  107. }
  108. /**
  109. * 登陆退出(当前账户) (todo 这儿应该登出当前token, (登出一个账号还是全端口登出))
  110. * @return true
  111. */
  112. public function logout()
  113. {
  114. self::clearToken($this->uid, $this->app_type, $this->request->adminToken());
  115. return true;
  116. }
  117. /**
  118. * 创建token
  119. * @param SysUser $userinfo
  120. * @param string $app_type
  121. * @return array
  122. */
  123. public function createToken(SysUser $userinfo, string $app_type)
  124. {
  125. $expire_time = env('system.admin_token_expire_time') ?? 3600;
  126. return TokenAuth::createToken($userinfo->uid, AppTypeDict::ADMIN, ['uid' => $userinfo->uid, 'username' => $userinfo->username], $expire_time);
  127. }
  128. /**
  129. * 清理token
  130. * @param int $uid
  131. * @param string|null $type
  132. * @param string|null $token
  133. */
  134. public static function clearToken(int $uid, ?string $type = '', ?string $token = '')
  135. {
  136. if (empty($type)) {
  137. TokenAuth::clearToken($uid, AppTypeDict::ADMIN, $token);//清除平台管理端的token
  138. // TokenAuth::clearToken($uid, AppTypeDict::SITE, $token);//清除站点管理端的token
  139. } else {
  140. TokenAuth::clearToken($uid, $type, $token);
  141. }
  142. }
  143. /**
  144. * 解析token
  145. * @param string|null $token
  146. * @return array
  147. */
  148. public function parseToken(?string $token)
  149. {
  150. if (empty($token)) {
  151. //定义专属于授权认证机制的错误响应, 定义专属语言包
  152. throw new AuthException('MUST_LOGIN', 401);
  153. }
  154. //暴力操作,截停所有异常覆盖为token失效
  155. try {
  156. $token_info = TokenAuth::parseToken($token, AppTypeDict::ADMIN);
  157. } catch ( Throwable $e ) {
  158. // if(env('app_debug', false)){
  159. // throw new AuthException($e->getMessage(), 401);
  160. // }else{
  161. throw new AuthException('LOGIN_EXPIRE', 401);
  162. // }
  163. }
  164. if (!$token_info) {
  165. throw new AuthException('MUST_LOGIN', 401);
  166. }
  167. //验证有效次数或过期时间
  168. return $token_info;
  169. }
  170. }