完善JWT认证逻辑
This commit is contained in:
parent
6b2eb3cff8
commit
4ec5166f50
@ -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;
|
||||
}
|
11
app/Controller/AuthController.php
Normal file
11
app/Controller/AuthController.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Hyperf\HttpServer\Annotation\Middleware;
|
||||
use Phper666\JWTAuth\Middleware\JWTAuthDefaultSceneMiddleware;
|
||||
|
||||
#[Middleware(JWTAuthDefaultSceneMiddleware::class)]
|
||||
class AuthController extends BaseController
|
||||
{
|
||||
}
|
@ -4,7 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Controller\PunchCard\User;
|
||||
|
||||
use App\Controller\BaseController;
|
||||
use App\Controller\AuthController;
|
||||
use App\JsonRpc\PunchCardSystemExternalServiceInterface;
|
||||
use App\JsonRpc\UserExternalServiceInterface;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
@ -13,7 +13,7 @@ use Hyperf\HttpServer\Annotation\GetMapping;
|
||||
use Hyperf\HttpServer\Annotation\PostMapping;
|
||||
|
||||
#[Controller(prefix: "kq")]
|
||||
class UserController extends BaseController
|
||||
class UserController extends AuthController
|
||||
{
|
||||
/**
|
||||
* 用户中心对外RPC服务
|
||||
|
@ -2,24 +2,32 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controller\PunchCard\Wechat;
|
||||
namespace App\Controller\PunchCard\User;
|
||||
|
||||
use App\Controller\BaseController;
|
||||
use App\Exception\BusinessException;
|
||||
use app\Constants\Wechat\AuthErrorCode;
|
||||
use App\Service\Wechat\AuthService;
|
||||
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 AuthController extends BaseController
|
||||
class WechatAuthController extends BaseController
|
||||
{
|
||||
/**
|
||||
* 微信授权服务
|
||||
*
|
||||
* @var WechatAuthService
|
||||
*/
|
||||
#[Inject]
|
||||
protected AuthService $service;
|
||||
protected WechatAuthService $service;
|
||||
|
||||
/**
|
||||
* 通过微信授权新建用户
|
||||
@ -37,4 +45,16 @@ class AuthController extends BaseController
|
||||
|
||||
return $this->service->codeToOpenID($code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新token
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
#[Middleware(JWTAuthDefaultSceneMiddleware::class)]
|
||||
#[GetMapping(path: "auth/refresh_token")]
|
||||
public function refreshToken() : array
|
||||
{
|
||||
return $this->service->refreshToken();
|
||||
}
|
||||
}
|
@ -1,17 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service\Wechat;
|
||||
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 AuthService
|
||||
class WechatAuthService
|
||||
{
|
||||
/**
|
||||
* 考勤系统小程序APPID
|
||||
@ -37,6 +40,14 @@ class AuthService
|
||||
#[Inject]
|
||||
protected UserExternalServiceInterface $userExternalService;
|
||||
|
||||
/**
|
||||
* JWT认证组件
|
||||
*
|
||||
* @var JWT
|
||||
*/
|
||||
#[Inject]
|
||||
protected JWT $jwt;
|
||||
|
||||
/**
|
||||
* 微信通过code获取session信息请求地址
|
||||
*
|
||||
@ -66,6 +77,46 @@ class AuthService
|
||||
throw new BusinessException($res['code'], $res['msg']);
|
||||
}
|
||||
|
||||
return ['openid' => $result['data']['openid']];
|
||||
if (empty($res['data']['user'])) {
|
||||
throw new BusinessException(AuthErrorCode::CODE_TO_AUTH_FAIL);
|
||||
}
|
||||
|
||||
$user_data = [
|
||||
'user_id' => $res['data']['user']['user_id'],
|
||||
'nickname' => $res['data']['user']['user_nickname'],
|
||||
'openid' => $res['data']['user']['user_openid']
|
||||
];
|
||||
|
||||
try {
|
||||
$token = $this->jwt->getToken('default', $user_data);
|
||||
} 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())
|
||||
];
|
||||
}
|
||||
}
|
@ -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
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",
|
||||
|
93
config/autoload/jwt.php
Normal file
93
config/autoload/jwt.php
Normal file
@ -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过期时间,单位为秒
|
||||
]
|
||||
]
|
||||
];
|
Loading…
Reference in New Issue
Block a user