hyperf-gateway/app/Service/User/WechatAuthService.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())
];
}
}