133 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			133 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| namespace App\Service\User;
 | |
| 
 | |
| use App\Constants\Wechat\AuthErrorCode;
 | |
| use App\Exception\BusinessException;
 | |
| use App\Helper\Curl;
 | |
| use App\JsonRpc\UserExternalServiceInterface;
 | |
| use Hyperf\Config\Annotation\Value;
 | |
| use Hyperf\Di\Annotation\Inject;
 | |
| use Phper666\JWTAuth\JWT;
 | |
| use Psr\SimpleCache\InvalidArgumentException;
 | |
| 
 | |
| /**
 | |
|  * 微信授权处理服务层
 | |
|  */
 | |
| class WechatAuthService
 | |
| {
 | |
|     /**
 | |
|      * 考勤系统小程序APPID
 | |
|      *
 | |
|      * @var string
 | |
|      */
 | |
|     #[Value("app.wechat_punch_card_appid")]
 | |
|     protected string $appid;
 | |
| 
 | |
|     /**
 | |
|      * 考勤系统小程序APPSecret
 | |
|      *
 | |
|      * @var string
 | |
|      */
 | |
|     #[Value("app.wechat_punch_card_secret")]
 | |
|     protected string $secret;
 | |
| 
 | |
|     /**
 | |
|      * 用户中心对外RPC服务
 | |
|      *
 | |
|      * @var UserExternalServiceInterface
 | |
|      */
 | |
|     #[Inject]
 | |
|     protected UserExternalServiceInterface $userExternalService;
 | |
| 
 | |
|     /**
 | |
|      * JWT认证组件
 | |
|      *
 | |
|      * @var JWT
 | |
|      */
 | |
|     #[Inject]
 | |
|     protected JWT $jwt;
 | |
| 
 | |
|     /**
 | |
|      * 微信通过code获取session信息请求地址
 | |
|      *
 | |
|      * @var string
 | |
|      */
 | |
|     protected string $wechat_auth_url = 'https://api.weixin.qq.com/sns/jscode2session';
 | |
| 
 | |
|     /**
 | |
|      * 通过微信授权新建用户
 | |
|      *
 | |
|      * @param string $code
 | |
|      * @return array
 | |
|      */
 | |
|     public function codeToOpenID(string $code) : array
 | |
|     {
 | |
|         $url = $this->wechat_auth_url . '?' . http_build_query([
 | |
|             'appid' => $this->appid,
 | |
|             'secret' => $this->secret,
 | |
|             'js_code' => $code,
 | |
|             'grant_type' => 'authorization_code'
 | |
|         ]);
 | |
| 
 | |
|         $result = Curl::get($url);
 | |
|         $res = $this->userExternalService->wechatNewUser($result['data']['openid']);
 | |
| 
 | |
|         if (!$res['code'] !== 200) {
 | |
|             throw new BusinessException($res['code'], $res['msg']);
 | |
|         }
 | |
| 
 | |
|         if (empty($res['data']['user'])) {
 | |
|             throw new BusinessException(AuthErrorCode::CODE_TO_AUTH_FAIL);
 | |
|         }
 | |
| 
 | |
|         return $this->getToken($res['data']['user']['user_id'], $res['data']['user']['user_nickname'], $res['data']['user']['user_openid']);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * 获取JWT认证token
 | |
|      *
 | |
|      * @param int $user_id
 | |
|      * @param string $nickname
 | |
|      * @param string $openid
 | |
|      * @return array
 | |
|      */
 | |
|     public function getToken(int $user_id, string $nickname, string $openid)
 | |
|     {
 | |
|         try {
 | |
|             $token = $this->jwt->getToken('default', [
 | |
|                 'user_id' => $user_id,
 | |
|                 'nickname' => $nickname,
 | |
|                 'openid' => $openid
 | |
|             ]);
 | |
|         } catch (InvalidArgumentException) {
 | |
|             // TODO 记录日志
 | |
|             throw new BusinessException(AuthErrorCode::CODE_TO_AUTH_FAIL);
 | |
|         }
 | |
| 
 | |
|         return [
 | |
|             'token' => $token->toString(),
 | |
|             'exp' => $this->jwt->getTTL($token->toString())
 | |
|         ];
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * 刷新token
 | |
|      *
 | |
|      * @return array
 | |
|      */
 | |
|     public function refreshToken() : array
 | |
|     {
 | |
|         try {
 | |
|             $token = $this->jwt->refreshToken();
 | |
|         } catch (InvalidArgumentException) {
 | |
|             // TODO 记录日志
 | |
|             throw new BusinessException(AuthErrorCode::CODE_TO_AUTH_FAIL);
 | |
|         }
 | |
| 
 | |
|         return [
 | |
|             'token' => $token->toString(),
 | |
|             'exp' => $this->jwt->getTTL($token->toString())
 | |
|         ];
 | |
|     }
 | |
| } |