develop #1

Merged
fantasticbin merged 15 commits from develop into master 2 years ago

@ -49,6 +49,6 @@ WORKDIR /opt/www
COPY . /opt/www
RUN composer install --no-dev -o && php bin/hyperf.php
EXPOSE 9901
EXPOSE 8401
ENTRYPOINT ["php", "/opt/www/bin/hyperf.php", "start"]

@ -25,5 +25,5 @@ class ErrorCode extends AbstractConstants
/**
* @Message("Something went wrong")
*/
public const COMMON_ERROR = 1000000;
public const COMMON_ERROR = 1200000;
}

@ -13,5 +13,10 @@ class AuthErrorCode extends AbstractConstants
/**
* @Message("请传入微信Code")
*/
public const CODE_EMPTY_ERROR = 2000001;
public const CODE_EMPTY_ERROR = 1200001;
/**
* @Message("授权失败")
*/
public const CODE_TO_AUTH_FAIL = 1200002;
}

@ -0,0 +1,119 @@
<?php
declare(strict_types=1);
namespace App\Controller\PunchCard\User;
use App\Controller\BaseController;
use App\JsonRpc\PunchCardSystemExternalServiceInterface;
use App\JsonRpc\UserExternalServiceInterface;
use App\Middleware\AuthMiddleware;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\PostMapping;
#[Middleware(AuthMiddleware::class)]
#[Controller(prefix: "kq")]
class UserController extends BaseController
{
/**
* 用户中心对外RPC服务
*
* @var UserExternalServiceInterface
*/
#[Inject]
protected UserExternalServiceInterface $userExternalService;
/**
* 考勤系统设置对外RPC服务
*
* @var PunchCardSystemExternalServiceInterface
*/
#[Inject]
protected PunchCardSystemExternalServiceInterface $punchCardSystemExternalService;
/**
* 获取个人资料
*
* @return array
*/
#[GetMapping(path: "user/information")]
public function information() : array
{
$user = $this->request->getAttribute('AuthUser');
return $this->getServiceResult($this->userExternalService->getUserInfo($user['openid'], [
'user_name',
'user_phone',
]));
}
/**
* 保存个人资料
*
* @return void
*/
#[PostMapping(path: "user/save_information")]
public function saveInformation() : void
{
$phone = $this->request->input('phone', '');
// TODO 逻辑完善
}
/**
* 获取问题反馈类型列表
*
* @return array
*/
#[GetMapping(path: "user/feedback_type")]
public function getFeedbackTypeList() : array
{
return $this->getServiceResult($this->punchCardSystemExternalService->getFeedbackTypeList());
}
/**
* 保存问题反馈
*
* @return array
*/
#[PostMapping(path: "user/save_feedback")]
public function saveFeedback() : array
{
$user = $this->request->getAttribute('AuthUser');
return $this->getServiceResult($this->punchCardSystemExternalService->saveFeedback($this->request, $user['user_id']));
}
/**
* 获取紧急联系人关系列表
*
* @return array
*/
#[GetMapping(path: "user/emergency_contact_kinship")]
public function getEmergencyContactKinshipList() : array
{
return $this->getServiceResult($this->userExternalService->getEmergencyContactKinshipList());
}
/**
* 保存紧急联系人
*
* @return array
*/
#[PostMapping(path: "user/add_emergency_contact")]
public function addEmergencyContact() : array
{
return $this->getServiceResult($this->userExternalService->addEmergencyContact($this->request));
}
/**
* 测试打印JWT认证信息
*
* @return array
*/
#[GetMapping(path: "user/test")]
public function test() : array
{
return $this->request->getAttribute('AuthUser');
}
}

@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace App\Controller\PunchCard\User;
use App\Controller\BaseController;
use App\Exception\BusinessException;
use app\Constants\Wechat\AuthErrorCode;
use App\Middleware\AuthMiddleware;
use App\Service\User\WechatAuthService;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Phper666\JWTAuth\Middleware\JWTAuthDefaultSceneMiddleware;
/**
* 微信授权处理控制器
*/
#[Controller(prefix: "kq")]
class WechatAuthController extends BaseController
{
/**
* 微信授权服务
*
* @var WechatAuthService
*/
#[Inject]
protected WechatAuthService $service;
/**
* 通过微信授权新建用户
*
* @return array
*/
#[RequestMapping(path: "auth/code2OpenID", methods: "get,post")]
public function code2OpenID() : array
{
$code = $this->request->input('code', '');
if (empty($code)) {
throw new BusinessException(AuthErrorCode::CODE_EMPTY_ERROR);
}
return $this->service->codeToOpenID($code);
}
/**
* 刷新token
*
* @return array
*/
#[Middleware(AuthMiddleware::class)]
#[GetMapping(path: "auth/refresh_token")]
public function refreshToken() : array
{
return $this->service->refreshToken();
}
}

@ -0,0 +1,96 @@
<?php
declare(strict_types=1);
namespace App\Controller;
use App\Exception\BusinessException;
use App\JsonRpc\UserExternalServiceInterface;
use App\Service\User\WechatAuthService;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\Utils\Collection;
use Hyperf\Paginator\Paginator;
/**
* 示例控制器
*/
#[AutoController]
class TestController extends BaseController
{
/**
* @var UserExternalServiceInterface
*/
#[Inject]
protected UserExternalServiceInterface $userService;
/**
* 返回数据示例
*
* @return array
*/
public function index() : array
{
$data['user_id'] = 'test';
return $data;
}
/**
* 空返回示例
*
* @return void
*/
public function empty() : void
{}
/**
* 错误示例
*
* @return mixed
*/
public function error(): mixed
{
throw new BusinessException(500, 'error');
}
/**
* 分页示例
*
* @return Paginator
*/
public function page() : Paginator
{
$currentPage = (int) $this->request->input('page', 1);
$perPage = (int) $this->request->input('per_page', 2);
// 这里根据 $currentPage 和 $perPage 进行数据查询,以下使用 Collection 代替
$collection = new Collection([
['id' => 1, 'name' => 'Tom'],
['id' => 2, 'name' => 'Sam'],
['id' => 3, 'name' => 'Tim'],
['id' => 4, 'name' => 'Joe'],
]);
$users = array_values($collection->forPage($currentPage, $perPage)->toArray());
return new Paginator($users, $perPage, $currentPage);
}
/**
* 获取token用于测试
*
* @param WechatAuthService $wechatAuthService
* @return array
*/
public function token(WechatAuthService $wechatAuthService) : array
{
$openid = $this->request->input('openid', '1111111');
$user = $this->getServiceResult($this->userService->getUserInfo($openid, ['user_id', 'user_nickname']));
if (!empty($user)) {
return $wechatAuthService->getToken($user['user_id'], $user['user_nickname'], $openid);
}
return [];
}
}

@ -1,40 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Controller\Wechat;
use App\Controller\BaseController;
use App\Exception\BusinessException;
use app\Constants\Wechat\AuthErrorCode;
use App\Service\Wechat\AuthService;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\PostMapping;
/**
* 微信授权处理控制器
*/
#[Controller]
class AuthController extends BaseController
{
#[Inject]
protected AuthService $service;
/**
* 通过微信授权新建用户
*
* @return array
*/
#[PostMapping(path: "auth/code2OpenID")]
public function code2OpenID() : array
{
$code = $this->request->input('code', '');
if (empty($code)) {
throw new BusinessException(AuthErrorCode::CODE_EMPTY_ERROR);
}
return $this->service->codeToOpenID($code);
}
}

@ -11,6 +11,8 @@ declare(strict_types=1);
*/
namespace App\Exception\Handler;
use App\Constants\ErrorCode;
use App\Helper\Result;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Stream\SwooleStream;
@ -25,9 +27,13 @@ class AppExceptionHandler extends ExceptionHandler
public function handle(Throwable $throwable, ResponseInterface $response)
{
$this->logger->error(sprintf('%s[%s] in %s', $throwable->getMessage(), $throwable->getLine(), $throwable->getFile()));
$this->logger->error($throwable->getTraceAsString());
return $response->withHeader('Server', 'Hyperf')->withStatus(500)->withBody(new SwooleStream('Internal Server Error.'));
$message = $throwable->getMessage();
$error = explode('|', $message, 2);
$code = $error[1] ?? $throwable->getCode() ?: ErrorCode::COMMON_ERROR;
$data = Result::error($code, $error[0]);
$responseStr = json_encode($data, JSON_UNESCAPED_UNICODE);
return $response->withHeader('Content-Type', 'application/json')->withBody(new SwooleStream($responseStr));
}
public function isValid(Throwable $throwable): bool

@ -4,22 +4,53 @@ declare(strict_types=1);
namespace App\Helper;
use App\Exception\BusinessException;
use GuzzleHttp\Client;
use Hyperf\Guzzle\HandlerStackFactory;
/**
* 请求处理公共类
*/
class Curl
{
public static function get(string $url) : array
/**
* 获取Guzzle客户端实例使用连接池
*
* @return Client
*/
protected static function getClient() : Client
{
$factory = new HandlerStackFactory();
$stack = $factory->create();
$client = make(Client::class, [
return make(Client::class, [
'config' => [
'handler' => $stack,
]
]);
$response = $client->get($url, ['timeout' => 2]);
}
/**
* 发送Get请求
*
* @param string $url
* @param array $headers
* @return array
*/
public static function get(string $url, array $headers = []) : array
{
$client = self::getClient();
$options = ['timeout' => 2, 'verify' => false];
if (!empty($headers)) {
$options['headers'] = $headers;
}
try {
$response = $client->get($url, $options);
} catch (\Throwable $throwable) {
throw new BusinessException($throwable->getCode(), $throwable->getMessage());
}
if ($response->getStatusCode() === 200) {
return json_decode($response->getBody()->getContents(), true);
@ -28,7 +59,33 @@ class Curl
return [];
}
public static function post(string $url, array $data = [])
/**
* 发送POST请求application/x-www-form-urlencoded
*
* @param string $url
* @param array $data
* @param array $headers
* @return array
*/
public static function post(string $url, array $data = [], array $headers = []) : array
{
$client = self::getClient();
$options = ['timeout' => 2, 'verify' => false, 'form_params' => $data];
if (!empty($headers)) {
$options['headers'] = $headers;
}
try {
$response = $client->post($url, $options);
} catch (\Throwable $throwable) {
throw new BusinessException($throwable->getCode(), $throwable->getMessage());
}
if ($response->getStatusCode() === 200) {
return json_decode($response->getBody()->getContents(), true);
}
return [];
}
}

@ -0,0 +1,36 @@
<?php
namespace App\JsonRpc;
use Hyperf\RpcClient\AbstractServiceClient;
use Hyperf\HttpServer\Contract\RequestInterface;
class PunchCardSystemExternalServiceConsumer extends AbstractServiceClient implements PunchCardSystemExternalServiceInterface
{
/**
* 定义对应服务提供者的服务名称
* @var string
*/
protected $serviceName = 'PunchCardSystemExternalService';
/**
* 获取问题反馈类型列表
*
* @return array
*/
public function getFeedbackTypeList() : array
{
return $this->__request(__FUNCTION__, []);
}
/**
* 保存问题反馈
*
* @param RequestInterface $request
* @return array
*/
public function saveFeedback(RequestInterface $request) : array
{
return $this->__request(__FUNCTION__, [...$request->all(), ...['user_id' => $request->getAttribute('AuthUser')['user_id']]]);
}
}

@ -0,0 +1,23 @@
<?php
namespace App\JsonRpc;
use Hyperf\HttpServer\Contract\RequestInterface;
interface PunchCardSystemExternalServiceInterface
{
/**
* 获取问题反馈类型列表
*
* @return array
*/
public function getFeedbackTypeList() : array;
/**
* 保存问题反馈
*
* @param RequestInterface $request
* @return array
*/
public function saveFeedback(RequestInterface $request) : array;
}

@ -0,0 +1,59 @@
<?php
namespace App\JsonRpc;
use Hyperf\RpcClient\AbstractServiceClient;
use Hyperf\HttpServer\Contract\RequestInterface;
class UserExternalServiceConsumer extends AbstractServiceClient implements UserExternalServiceInterface
{
/**
* 定义对应服务提供者的服务名称
* @var string
*/
protected $serviceName = 'UserExternalService';
/**
* 获取用户信息
*
* @param string $openid
* @param array $field
* @return array
*/
public function getUserInfo(string $openid, array $field = []) : array
{
return $this->__request(__FUNCTION__, compact('openid', 'field'));
}
/**
* 通过微信授权新建用户
*
* @param string $openid
* @return array
*/
public function wechatNewUser(string $openid) : array
{
return $this->__request(__FUNCTION__, compact('openid'));
}
/**
* 获取紧急联系人关系列表
*
* @return array
*/
public function getEmergencyContactKinshipList() : array
{
return $this->__request(__FUNCTION__, []);
}
/**
* 保存紧急联系人
*
* @param RequestInterface $request
* @return array
*/
public function addEmergencyContact(RequestInterface $request) : array
{
return $this->__request(__FUNCTION__, $request->all());
}
}

@ -2,13 +2,39 @@
namespace App\JsonRpc;
use Hyperf\HttpServer\Contract\RequestInterface;
interface UserExternalServiceInterface
{
/**
* 获取用户信息
*
* @param string $openid
* @param array $field
* @return array
*/
public function getUserInfo(string $openid, array $field = []) : array;
/**
* 通过微信授权新建用户
*
* @param string $open_id
* @param string $openid
* @return array
*/
public function wechatNewUser(string $openid) : array;
/**
* 获取紧急联系人关系列表
*
* @return array
*/
public function getEmergencyContactKinshipList() : array;
/**
* 保存紧急联系人
*
* @param RequestInterface $request
* @return array
*/
public function wechatNewUser(string $open_id) : array;
public function addEmergencyContact(RequestInterface $request) : array;
}

@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
namespace App\Middleware;
use App\Constants\ErrorCode;
use Hyperf\Context\Context;
use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;
use Phper666\JWTAuth\Exception\JWTException;
use Phper666\JWTAuth\Util\JWTUtil;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Phper666\JWTAuth\JWT;
use Phper666\JWTAuth\Exception\TokenValidException;
/**
* jwt token 校验的中间件,校验场景是否一致
*/
class AuthMiddleware implements MiddlewareInterface
{
public function __construct(protected HttpResponse $response, protected JWT $jwt)
{
}
/**
* @param ServerRequestInterface $request
* @param RequestHandlerInterface $handler
* @return ResponseInterface
* @throws \Psr\SimpleCache\InvalidArgumentException
* @throws \Throwable
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$token = $request->getHeaderLine('Authorization') ?? '';
if ($token === "") {
throw new JWTException('Missing token', ErrorCode::COMMON_ERROR);
}
$token = JWTUtil::handleToken($token);
if ($token !== false && $this->jwt->verifyTokenAndScene('default', $token)) {
// 封装认证用户信息
$request = $request->withAttribute('AuthUser', JWTUtil::getParserData($request));
Context::set(ServerRequestInterface::class, $request);
return $handler->handle($request);
}
throw new TokenValidException('Token authentication does not pass', ErrorCode::COMMON_ERROR);
}
}

@ -0,0 +1,133 @@
<?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())
];
}
}

@ -1,48 +0,0 @@
<?php
namespace App\Service\Wechat;
use App\Exception\BusinessException;
use App\Helper\Curl;
use App\JsonRpc\UserExternalServiceInterface;
use Hyperf\Config\Annotation\Value;
use Hyperf\Di\Annotation\Inject;
class AuthService
{
#[Value("app.wechat_punch_card_appid")]
protected string $appid;
#[Value("app.wechat_punch_card_secret")]
protected string $secret;
#[Inject]
protected UserExternalServiceInterface $userExternalService;
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']);
}
return ['openid' => $result['data']['openid']];
}
}

@ -34,7 +34,8 @@
"hyperf/rpc-client": "~2.2.0",
"hyperf/rpc-server": "~2.2.0",
"hyperf/service-governance-consul": "~2.2.0",
"hyperf/validation": "^2.2"
"hyperf/validation": "^2.2",
"phper666/jwt-auth": "~4.0.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.0",

184
composer.lock generated

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "7cc40bd39d6d590a4e06bfb1d56c0abb",
"content-hash": "7f8915491bc01099466689096453ac63",
"packages": [
{
"name": "doctrine/annotations",
@ -2515,6 +2515,101 @@
],
"time": "2022-10-10T19:10:24+00:00"
},
{
"name": "lcobucci/clock",
"version": "2.2.0",
"dist": {
"type": "zip",
"url": "https://mirrors.cloud.tencent.com/repository/composer/lcobucci/clock/2.2.0/lcobucci-clock-2.2.0.zip",
"reference": "fb533e093fd61321bfcbac08b131ce805fe183d3",
"shasum": ""
},
"require": {
"php": "^8.0",
"stella-maris/clock": "^0.1.4"
},
"require-dev": {
"infection/infection": "^0.26",
"lcobucci/coding-standard": "^8.0",
"phpstan/extension-installer": "^1.1",
"phpstan/phpstan": "^0.12",
"phpstan/phpstan-deprecation-rules": "^0.12",
"phpstan/phpstan-phpunit": "^0.12",
"phpstan/phpstan-strict-rules": "^0.12",
"phpunit/phpunit": "^9.5"
},
"type": "library",
"autoload": {
"psr-4": {
"Lcobucci\\Clock\\": "src"
}
},
"license": [
"MIT"
],
"authors": [
{
"name": "Luís Cobucci",
"email": "lcobucci@gmail.com"
}
],
"description": "Yet another clock abstraction",
"time": "2022-04-19T19:34:17+00:00"
},
{
"name": "lcobucci/jwt",
"version": "4.1.5",
"dist": {
"type": "zip",
"url": "https://mirrors.cloud.tencent.com/repository/composer/lcobucci/jwt/4.1.5/lcobucci-jwt-4.1.5.zip",
"reference": "fe2d89f2eaa7087af4aa166c6f480ef04e000582",
"shasum": ""
},
"require": {
"ext-hash": "*",
"ext-json": "*",
"ext-mbstring": "*",
"ext-openssl": "*",
"ext-sodium": "*",
"lcobucci/clock": "^2.0",
"php": "^7.4 || ^8.0"
},
"require-dev": {
"infection/infection": "^0.21",
"lcobucci/coding-standard": "^6.0",
"mikey179/vfsstream": "^1.6.7",
"phpbench/phpbench": "^1.0",
"phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "^0.12",
"phpstan/phpstan-deprecation-rules": "^0.12",
"phpstan/phpstan-phpunit": "^0.12",
"phpstan/phpstan-strict-rules": "^0.12",
"phpunit/php-invoker": "^3.1",
"phpunit/phpunit": "^9.5"
},
"type": "library",
"autoload": {
"psr-4": {
"Lcobucci\\JWT\\": "src"
}
},
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Luís Cobucci",
"email": "lcobucci@gmail.com",
"role": "Developer"
}
],
"description": "A simple library to work with JSON Web Token and JSON Web Signature",
"keywords": [
"JWS",
"jwt"
],
"time": "2021-09-28T19:34:56+00:00"
},
{
"name": "markrogoyski/math-php",
"version": "v2.6.0",
@ -3020,6 +3115,56 @@
],
"time": "2020-10-12T12:39:22+00:00"
},
{
"name": "phper666/jwt-auth",
"version": "v4.0.7",
"dist": {
"type": "zip",
"url": "https://mirrors.cloud.tencent.com/repository/composer/phper666/jwt-auth/v4.0.7/phper666-jwt-auth-v4.0.7.zip",
"reference": "c42e1ef968d300e7e74e449e5e93cda7d22de33f",
"shasum": ""
},
"require": {
"ext-swoole": ">=4.4",
"lcobucci/jwt": "4.1.5",
"nesbot/carbon": "^1.0 || ^2.0",
"php": ">=7.4"
},
"suggest": {
"hyperf/cache": "required hyperf/cache ~2.2.0",
"hyperf/command": "required hyperf/command ~2.2.0",
"hyperf/config": "required hyperf/config ~2.2.0",
"hyperf/di": "required hyperf/di ~2.2.0"
},
"type": "library",
"extra": {
"hyperf": {
"config": "Phper666\\JWTAuth\\ConfigProvider"
}
},
"autoload": {
"psr-4": {
"Phper666\\JWTAuth\\": "src/"
}
},
"license": [
"MIT"
],
"authors": [
{
"name": "Li Yuzhao",
"email": "562405704@qq.com",
"homepage": "https://github.com/phper666/jwt-auth",
"role": "Developer"
}
],
"description": "jwt-auth Component",
"keywords": [
"hyperf",
"php"
],
"time": "2022-04-19T11:54:50+00:00"
},
{
"name": "phpoption/phpoption",
"version": "1.9.0",
@ -3628,6 +3773,43 @@
"description": "A polyfill for getallheaders.",
"time": "2019-03-08T08:55:37+00:00"
},
{
"name": "stella-maris/clock",
"version": "0.1.6",
"dist": {
"type": "zip",
"url": "https://mirrors.cloud.tencent.com/repository/composer/stella-maris/clock/0.1.6/stella-maris-clock-0.1.6.zip",
"reference": "a94228dac03c9a8411198ce8c8dacbbe99c930c3",
"shasum": ""
},
"require": {
"php": "^7.0|^8.0"
},
"type": "library",
"autoload": {
"psr-4": {
"StellaMaris\\Clock\\": "src"
}
},
"license": [
"MIT"
],
"authors": [
{
"name": "Andreas Heigl",
"role": "Maintainer"
}
],
"description": "A pre-release of the proposed PSR-20 Clock-Interface",
"homepage": "https://gitlab.com/stella-maris/clock",
"keywords": [
"clock",
"datetime",
"point in time",
"psr20"
],
"time": "2022-09-27T15:03:11+00:00"
},
{
"name": "symfony/console",
"version": "v5.4.11",

@ -9,5 +9,11 @@ declare(strict_types=1);
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
use Hyperf\JsonRpc\JsonRpcPoolTransporter;
use Hyperf\JsonRpc\JsonRpcTransporter;
return [
JsonRpcTransporter::class => JsonRpcPoolTransporter::class,
App\JsonRpc\UserExternalServiceInterface::class => App\JsonRpc\UserExternalServiceConsumer::class,
App\JsonRpc\PunchCardSystemExternalServiceInterface::class => App\JsonRpc\PunchCardSystemExternalServiceConsumer::class,
];

@ -0,0 +1,93 @@
<?php
declare(strict_types=1);
return [
/**
* 不需要检查的路由如果使用jwt提供的默认中间件可以对某些不用做检验的路由进行配置例如登录等
* 具体的逻辑可以效仿JWT提供的默认中间件
* [
* ["GET", "/index/test"],
* ["**", "/test"]
* ]
*
* 第一个填写请求方法('**'代表支持所有的请求方法),第二个填写路由路径('/**'代表支持所有的路径)
* 如果数组中存在["**", "/**"]则默认所有的请求路由都不做jwt token的校验直接放行如果no_check_route为一个空数组
* 所有的请求路由都需要做jwt token校验
* 路由路径支持正则的写法
* 正则写法:["**", "/api/{name:.+}"] 支持模块化不做jwt token的校验例如/api/login/login
*/
'no_check_route' => [
// ["**", "/**"],
],
'login_type' => env('JWT_LOGIN_TYPE', 'mpop'), // 登录方式sso为单点登录同一个用户只能登录一个端mpop为多点登录
/**
* 单点登录自定义数据中必须存在uid的键值这个key你可以自行定义只要自定义数据中存在该键即可
*/
'sso_key' => 'user_id',
/**
* 只能用于Hmac包下的加密非对称算法其它的都会使用公私钥
*/
'secret' => env('JWT_SECRET', 'juzhongGroup'),
/**
* JWT 权限keys
* 对称算法: HS256, HS384 & HS512 使用 `JWT_SECRET`.
* 非对称算法: RS256, RS384 & RS512 / ES256, ES384 & ES512 使用下面的公钥私钥,需要自己去生成.
*/
'keys' => [
'public' => env('JWT_PUBLIC_KEY'), // 公钥,例如:'file:///path/to/public/key'
'private' => env('JWT_PRIVATE_KEY'), // 私钥,例如:'file:///path/to/private/key'
/**
* 你的私钥的密码。不需要密码可以不用设置
*/
'passphrase' => env('JWT_PASSPHRASE'),
],
'ttl' => env('JWT_TTL', 7200), // token过期时间单位为秒
/**
* 支持的对称算法HS256、HS384、HS512
* 支持的非对称算法RS256、RS384、RS512、ES256、ES384、ES512
*/
'alg' => env('JWT_ALG', 'HS256'), // jwt的hearder加密算法
/**
* jwt使用到的缓存前缀
* 建议使用独立的redis做缓存这样比较好做分布式
*/
'cache_prefix' => 'juzhong:jwt',
/**
* 是否开启黑名单单点登录和多点登录的注销、刷新使原token失效必须要开启黑名单目前黑名单缓存只支持hyperf缓存驱动
*/
'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true),
/**
* 黑名单的宽限时间 单位为:秒,注意:如果使用单点登录,该宽限时间无效
*/
'blacklist_grace_period' => env('JWT_BLACKLIST_GRACE_PERIOD', 0),
/**
* 签发者
*/
'issued_by' => 'phper666/jwt',
/**
* 区分不同场景的token比如你一个项目可能会有多种类型的应用接口鉴权,下面自行定义,我只是举例子
* 下面的配置会自动覆盖根配置比如application1会里面的数据会覆盖掉根数据
* 下面的scene会和根数据合并
* scene必须存在一个default
* 什么叫根数据这个配置的一维数组除了scene都叫根配置
*/
'scene' => [
'default' => [
'secret' => 'juzhongGroup', // 非对称加密使用字符串,请使用自己加密的字符串
'login_type' => 'mpop', // 登录方式sso为单点登录mpop为多点登录
'ttl' => 7200, // token过期时间单位为秒
]
]
];

@ -21,7 +21,7 @@ return [
'name' => 'http',
'type' => Server::SERVER_HTTP,
'host' => '0.0.0.0',
'port' => 9901,
'port' => 8401,
'sock_type' => SWOOLE_SOCK_TCP,
'callbacks' => [
Event::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest'],
@ -31,7 +31,7 @@ return [
'name' => 'jsonrpc-http',
'type' => Server::SERVER_HTTP,
'host' => '0.0.0.0',
'port' => 9902,
'port' => 8402,
'sock_type' => SWOOLE_SOCK_TCP,
'callbacks' => [
Event::ON_REQUEST => [\Hyperf\JsonRpc\HttpServer::class, 'onRequest'],

@ -18,7 +18,8 @@ return [
$consumers = [];
// 这里示例自动创建代理消费者类的配置形式,顾存在 name 和 service 两个配置项,这里的做法不是唯一的,仅说明可以通过 PHP 代码来生成配置
$services = [
'UserExternalService' => App\JsonRpc\UserExternalServiceInterface::class,
'UserExternalService' => '',
'PunchCardSystemExternalService' => ''
];
foreach ($services as $name => $interface) {
$consumers[] = [

Loading…
Cancel
Save