Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。
JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。
用户使用用户名和口令到认证服务器上请求认证。
认证服务器验证用户名和口令后,以服务器端生成
JWT Token
,这个token的生成过程如下:
- 认证服务器还会生成一个
Secret Key
(密钥)- 对
JWT Header
和JWT Payload
分别求Base64
。在Payload
可能包括了用户的抽象ID
和的过期时间
。- 用密钥对JWT签名
HMAC-SHA256(SecertKey, Base64UrlEncode(JWT-Header)+'.'+Base64UrlEncode(JWT-Payload))
然后把
base64(header).base64(payload).signature
作为JWT token
返回客户端。客户端使用JWT Token向应用服务器发送相关的请求。这个JWT Token就像一个临时用户权证一样。
composer require tinywan/jwt
use Tinywan\Jwt\JwtToken;
$user = [
'id' => 2022, // 这里必须是一个全局抽象唯一id
'name' => 'Tinywan',
'email' => 'Tinywan@163.com'
];
$token = JwtToken::generateToken($user);
var_dump(json_encode($token));
输出(json格式)
{
"token_type": "Bearer",
"expires_in": 36000,
"access_token": "eyJ0eXAiOiJAUR-Gqtnk9LUPO8IDrLK7tjCwQZ7CI...",
"refresh_token": "eyJ0eXAiOiJIEGkKprvcccccQvsTJaOyNy8yweZc..."
}
响应参数
参数 | 类型 | 描述 | 示例值 |
---|---|---|---|
token_type | string | Token 类型 | Bearer |
expires_in | int | 凭证有效时间,单位:秒 | 36000 |
access_token | string | 访问凭证 | XXXXXXXXXXXXXXXXXXXX |
refresh_token | string | 刷新凭证(访问凭证过期使用 ) | XXXXXXXXXXXXXXXXXXX |
1、获取当前
uid
$uid = JwtToken::getCurrentId();
2、获取所有字段
$email = JwtToken::getExtend();
3、获取自定义字段
$email = JwtToken::getExtendVal('email');
4、刷新令牌(通过刷新令牌获取访问令牌)
$refreshToken = JwtToken::refreshToken();
5、获取令牌有效期剩余时长(单位:秒)
$exp = JwtToken::getTokenExp();
6、单设备登录。默认是关闭,开启请修改配置文件
config/plugin/tinywan/jwt
'is_single_device' => true,
JWT 最常见的几种签名算法(JWA):HS256(HMAC-SHA256)
、RS256(RSA-SHA256)
还有 ES256(ECDSA-SHA256)
JWT 算法列表如下
+--------------+-------------------------------+--------------------+
| "alg" Param | Digital Signature or MAC | Implementation |
| Value | Algorithm | Requirements |
+--------------+-------------------------------+--------------------+
| HS256 | HMAC using SHA-256 | Required |
| HS384 | HMAC using SHA-384 | Optional |
| HS512 | HMAC using SHA-512 | Optional |
| RS256 | RSASSA-PKCS1-v1_5 using | Recommended |
| | SHA-256 | |
| RS384 | RSASSA-PKCS1-v1_5 using | Optional |
| | SHA-384 | |
| RS512 | RSASSA-PKCS1-v1_5 using | Optional |
| | SHA-512 | |
| ES256 | ECDSA using P-256 and SHA-256 | Recommended+ |
| ES384 | ECDSA using P-384 and SHA-384 | Optional |
| ES512 | ECDSA using P-521 and SHA-512 | Optional |
| PS256 | RSASSA-PSS using SHA-256 and | Optional |
| | MGF1 with SHA-256 | |
| PS384 | RSASSA-PSS using SHA-384 and | Optional |
| | MGF1 with SHA-384 | |
| PS512 | RSASSA-PSS using SHA-512 and | Optional |
| | MGF1 with SHA-512 | |
| none | No digital signature or MAC | Optional |
| | performed | |
+--------------+-------------------------------+--------------------+
The use of "+" in the Implementation Requirements column indicates
that the requirement strength is likely to be increased in a future
version of the specification.
可以看到被标记为 Recommended 的只有 RS256 和 ES256。
插件安装默认使用
HS256
对称加密算法。
HS256 使用同一个「secret_key」
进行签名与验证。一旦 secret_key
泄漏,就毫无安全性可言了。因此 HS256 只适合集中式认证,签名和验证都必须由可信方进行。
RS256 系列是使用 RSA 私钥进行签名,使用 RSA 公钥进行验证。
公钥即使泄漏也毫无影响,只要确保私钥安全就行。RS256 可以将验证委托给其他应用,只要将公钥给他们就行。
ssh-keygen -t rsa -b 4096 -E SHA512 -m PEM -P "" -f RS512.key
openssl rsa -in RS512.key -pubout -outform PEM -out RS512.key.pub
ssh-keygen -t rsa -b 4096 -E SHA354 -m PEM -P "" -f RS384.key
openssl rsa -in RS384.key -pubout -outform PEM -out RS384.key.pub
ssh-keygen -t rsa -b 4096 -E SHA256 -m PEM -P "" -f RS256.key
openssl rsa -in RS256.key -pubout -outform PEM -out RS256.key.pub
不懂的同学可以了解一下视频,会有详细的说明哦
想啥来啥,mark一波
牛逼
compsoer安装 php版本 限制是否可以去掉,当前生产环境是 7.3 没用到 7.4
已经移除PHP版本限制
请问还需要配置什么么
webman/console 版本太低了,升级一下
在config下面手动创建了一个
ok了
默认配置文件都是有的,就是使用的插件的app,如果没有,你看看是不是你的console这个插件的版本比较低。更多参考:https://www.workerman.net/q/7871
在中间件里面使用为什么获取不到任何数据?

已经封装好的,为啥要自己重新搞?
更多参考:https://github.com/Tinywan/webman-admin
expires_in int 凭证有效时间,单位:秒 36000
如何设置expires_in有效时间
修改配置文件
config/plugin/tinywan/jwt/app.php
access令牌过期时间,单位秒Bearer验证中的凭证格式有误,中间必须有个空格
您好 提示这个是什么错误?
后面看到了,谢谢
JWT使用
Bearer
验证关于插件,我想问下,如果token已经过期,我还能通过getTokenExp 获取到负数的剩余时长吗?
不行,过期时间返回是一个正整数,必须在过期前获取是否小于等于0。否则或抛出一个异常
单设备登录是通过redis实现的?
是的
楼主,是否考虑增加jwt过期时间容错功能,譬如token过期后30秒或者1分钟内还能有效,这个可以解决并发和自动续期问题
感谢你的建议,你的token既然已经过期了,为什么还要在30秒或者1分钟内还能有效?这个是不是自相矛盾了。你的并发和自动续期问题可否详细说明一下
生产环境使用php7.4报以上错误
请使用composer官方源下载
请问token错误如何返回自己的message格式,而不是返回异常
请问token错误如何返回自己的message格式,而不是返回异常?
后台管理和用户端的id有可能重复 怎么避免?
@wang5955616 试试我的多应用 https://www.workerman.net/plugin/45
如果获取token的时候,后台的id=1 用户端id=1 JwtToken::getCurrentId(); 获取的也是1 用自定义字段来判断是用户还是管理员嘛?
是的,通过获取扩展字段函数
例如我们是通过
is_admin
这个扩展表示获取当前登录用户的身份信息如何设置不同的令牌过期时间!例如 前台用户过期10天 后台管理用户过期30分钟
增加扩展字段即可