JWT TOKEN验证

安装
composer require tinywan/jwt
配置文件路径
/config/plugin/tinywan/jwt/app.php
接入中间件
namespace app\middleware;

use support\Redis;
use Tinywan\Jwt\JwtToken;
use Webman\Http\Request;
use Webman\Http\Response;
use Webman\MiddlewareInterface;

class AuthTokenMiddleware extends BaseController implements MiddlewareInterface
{

    public function process(Request $request, callable $handler): Response
    {
        try {
            JwtToken::verify();
        } catch (\Throwable $e) {
            return $this->error('登录状态有误,请重新登录',10003);
        }
        $tokenInfo = JwtToken::getExtend();
        if(!$tokenInfo['id']){
            return $this->error('登录状态有误,请重新登录',10000);
        }
        $key = "routineUser:" . $tokenInfo['id'];
        Redis::del($key);
        $redisInfo = Redis::get($key);
        if($redisInfo){
             $uInfo = json_decode($redisInfo,true);
        }else{
            $uInfo = (new WechatUsersLogic())->getInfo([['id','=',$tokenInfo['id']]]);
            $uInfo['wechat_setting'] = $tokenInfo['wechat_setting'];
//            $uInfo['code'] = $tokenInfo['code'];
            $uInfo['pid'] = $tokenInfo['pid'];
            Redis::set($key,json_encode($uInfo));
        }
        $request->routineUser = $uInfo;
        if(empty($request->routineUser)){
            return $this->error('登录状态有误,请重新登录',10000);
        }
        if($request->routineUser['is_del'] !== 0){
            return $this->error('账号已被冻结 请联系管理员',10002);
        }
        /** @var Response $response */
        $response = $handler($request);
        // Add cross domain HTTP header
        /*$response->withHeaders([
            'Access-Control-Allow-Origin'      => '*',
            'Access-Control-Allow-Credentials' => 'true',
        ]);*/
        return $response;
    }
}
生成Token
#[RequestMapping(["/login"], methods: ['GET', 'POST', 'OPTIONS'])]
#[Apidoc\Title("登录注册")]
#[Apidoc\Url("/webapi/user/login")]
#[Apidoc\Method("POST,GET")]
#[Apidoc\ParamType("formdata")]
#[Apidoc\Param("account", type: "string", require: true, default: "0xFFabddf5d772662bBb5Fe358D6cDFEDE5B795e15", desc: "区块链地址")]
#[Apidoc\Param("invite", type: "string", require: true, default: "OzGGBB23Vc", desc: "邀请码")]
#[Apidoc\Returned("authorization", type: "string", default: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ3ZWJtYW4udGlueXdhbi5jbiIsImF1ZCI6IndlYm1hbi50aW55d2FuLmNuIiwiaWF0IjoxNzA4NTkzMzM4LCJuYmYiOjE3MDg1OTMzMzgsImV4cCI6MTcwOTE5ODEzOCwiZXh0ZW5kIjp7ImlkIjoyfX0._2Bed8AdUvSCe7-TEP0-1yC_n5_b-bSddXCx76GdES0", desc: "authorization")]
public function login(Request $request): Response
{
    $key = "login" ;
    if (Redis::setNx($key, 1)) {
        Redis::expire($key, 1);
    } else {
        return error(lang($request, '操作太频繁,请稍后再试!'));
    }
    $tokenData = JwtToken::generateToken([
        'id' => 1, // 这里必须是一个全局抽象唯一id
    ]);
    return success(lang($request, '操作成功'), ['aToken' => $tokenData['access_token'],'rToken'=>$tokenData['refresh_token']]);
}
刷新Token
    #[Apidoc\Title("刷新TOKEN")]
    #[Apidoc\Url("/webapi/common/refreshToken")]
    #[Apidoc\Method("POST,GET")]
    #[Apidoc\ParamType("formdata")]
    #[Apidoc\Returned("origin_name", type: "string", default: "u=3019768837,3832590544&fm=253&fmt=auto&app=138&f=JPEG.webp", desc: "文件原名")]
    #[Apidoc\Returned("save_name", type: "string", default: "593f53411eb2e08c28dd0f15b555b7dc0bf83aae.webp", desc: "存储后文件名")]
    #[Apidoc\Returned("save_path", type: "string", default: "E:\\phpstudy_pro\\WWW\\QianYi\\Dapp\\mining\\public/uploads/20240222\\593f53411eb2e08c28dd0f15b555b7dc0bf83aae.webp", desc: "存储路径")]
    #[Apidoc\Returned("url", type: "string", default: "/uploads/20240222\\593f53411eb2e08c28dd0f15b555b7dc0bf83aae.webp", desc: "展示路径")]
    #[Apidoc\Returned("extension", type: "string", default: "webp", desc: "图片后缀")]
    #[RequestMapping(["/refreshToken"], methods: ['GET', 'POST', 'OPTIONS'])]
    public function refreshToken($request): Response
    {
        try {
            $tokenData = JwtToken::refreshToken();
        }catch (\Throwable $e){
            return error(lang($request,$e->getMessage()));
        }
        return success(lang($request, '操作成功'), ['aToken' => $tokenData['access_token'],'rToken'=>$tokenData['refresh_token']]);
    }
JWT文档描述
**响应参数**

| 参数|类型|描述|示例值|
|:---|:---|:---|:---|
|token_type| string |Token 类型 | Bearer |
|expires_in| int |凭证有效时间,单位:秒 | 36000 |
|access_token| string |访问凭证 | XXXXXXXXXXXXXXXXXXXX|
|refresh_token| string | 刷新凭证(访问凭证过期使用 ) | XXXXXXXXXXXXXXXXXXXX|

## 支持函数列表

1、获取当前`id`
```php
$id = Tinywan\Jwt\JwtToken::getCurrentId();
```

2、获取所有字段
```php
$email = Tinywan\Jwt\JwtToken::getExtend();
```

3、获取自定义字段
```php
$email = Tinywan\Jwt\JwtToken::getExtendVal('email');
```

4、刷新令牌(通过刷新令牌获取访问令牌)
```php
$refreshToken = Tinywan\Jwt\JwtToken::refreshToken();
```

5、获令牌有效期剩余时长
```php
$exp = Tinywan\Jwt\JwtToken::getTokenExp();
```

6、单设备登录。默认是关闭,开启请修改配置文件`config/plugin/tinywan/jwt`
```php
'is_single_device' => true,
```
> 单设备登录支持定义客户端 `client` 字段,自定义客户端单点登录(默认为`WEB`,即网页端),如:`MOBILE`、`APP`、`WECHAT`、`WEB`、`ADMIN`、`API`、`OTHER`等等
```php
$user = [
    'id'  => 2022,
    'name'  => 'Tinywan',
    'client' => 'MOBILE',
];
$token = Tinywan\Jwt\JwtToken::generateToken($user);
var_dump(json_encode($token));
```

7、获取当前用户信息(模型)
```php
$user = Tinywan\Jwt\JwtToken::getUser();
```
该配置项目`'user_model'`为一个匿名函数,默认返回空数组,可以根据自己项目ORM定制化自己的返回模型

**ThinkORM** 配置
```php
'user_model' => function($uid) {
// 返回一个数组
return \think\facade\Db::table('resty_user')
	->field('id,username,create_time')
	->where('id',$uid)
	->find();
}
```

**LaravelORM** 配置

```php
'user_model' => function($uid) {
// 返回一个对象
return \support\Db::table('resty_user')
	->where('id', $uid)
	->select('id','email','mobile','create_time')
	->first();
}
```

8、令牌清理
```php
$res = Tinywan\Jwt\JwtToken::clear();
```
> 只有配置项 `is_single_device`为`true` 才会生效。可选参数:`MOBILE`、`APP`、`WECHAT`、`WEB`、`ADMIN`、`API`、`OTHER`等等

9、自定义终端`client`
```php
// 生成WEB令牌
$user = [
    'id'  => 2022,
    'name'  => 'Tinywan',
    'client' => JwtToken::TOKEN_CLIENT_WEB
];
$token = JwtToken::generateToken($user);

// 生成移动端令牌
$user = [
    'id'  => 2022,
    'name'  => 'Tinywan',
    'client' => JwtToken::TOKEN_CLIENT_MOBILE
];
$token = JwtToken::generateToken($user);
```
默认是`WEB`端

10、自定义访问令牌和刷新令牌过期时间

```php
$extend = [
    'id'  => 2024,
    'access_exp'  => 7200,  // 2 小时
];
$token = Tinywan\Jwt\JwtToken::generateToken($extend);
```

11、令牌过期错误码

* 访问令牌
  * 身份验证令牌无效:`401011`
  * 身份验证令牌尚未生效:`401012`
  * 身份验证会话已过期,请重新登录!:`401013`
  * 获取的扩展字段不存在:`401014`
  * 访问令牌未知错误:`401015`
* 刷新令牌
  * 刷新令牌无效:`401021`
  * 刷新令牌尚未生效:`401022`
  * 刷新令牌会话已过期,请再次登录!:`401023`
  * 刷新令牌获取的扩展字段不存在:`401024`
  * 刷新令牌未知错误:`401025`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值