PHP JWT token加密

前言

关于jwt的介绍这里就不阐述了,相信你已经在网上看到了N篇介绍文章(你丫的讲那么多介绍到是告诉我怎么样呀!),关于php使用jwt的相关的使用却少的可怜,有的也看的模模糊糊,于是就自己整理,也方便自己以后进行查看。

jwt版本

php中jwt有3个版本:2.0、2.2、3.0。so!我们选择的是3.0的版本。别问为什么,你买电子产品都是买新不买旧呢。(说到这,想到了即将到手的iphonex,隐隐肾疼) ,看图可以发现3.0的版本支持更多参数。具体参数下面会解释

这里写图片描述

安装

1、使用composer安装

composer require lcobucci/jwt

 

2、从github上下载

点我跳转到github地址

依赖

  • PHP 5.5+
  • OpenSSL扩展

使用

参数解释

在使用之前先解释下上面参数的意思:

名称解释
iss (issuer)issuer 请求实体,可以是发起请求的用户的信息,也可是jwt的签发者
sub (Subject)设置主题,类似于发邮件时的主题
aud (audience)接收jwt的一方
exp (expire)token过期时间
nbf (not before)当前时间在nbf设定时间之前,该token无法使用
iat (issued at)token创建时间
jti (JWT ID)对当前token设置唯一标示

生成token

使用秘钥签名

use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Hmac\Sha256;

$builder = new Builder();
$signer = new Sha256();
// 设置发行人
$builder->setIssuer('http://example.com'); 
// 设置接收人
$builder->setAudience('http://example.org'); 
// 设置id
$builder->setId('4f1g23a12aa', true); 
// 设置生成token的时间
$builder->setIssuedAt(time()); 
// 设置在60秒内该token无法使用
$builder->setNotBefore(time() + 60); 
// 设置过期时间
$builder->setExpiration(time() + 3600); 
// 给token设置一个id
$builder->set('uid', 1); 
// 对上面的信息使用sha256算法签名
$builder->sign($signer, '签名key');
// 获取生成的token
$token = $builder->getToken();

使用RSA和ECDSA签名

RSA和ECDSA签名是基于公钥和私钥,所以必须使用私钥生成和验证使用

use Lcobucci\JWT\Signer\Keychain;
// 注意这里使用的sha256
use Lcobucci\JWT\Signer\Rsa\Sha256; 

$signer = new Sha256();
$keychain = new Keychain();

$builder = new Builder();
$builder->setIssuer('http://example.com');
$builder->setAudience('http://example.org');
$builder->setId('4f1g23a12aa', true);
$builder->setIssuedAt(time());
$builder->setNotBefore(time() + 60);
$builder->setExpiration(time() + 3600);
$builder->set('uid', 1);
// 与上面不同的是这里使用的是你的私钥,并提供私钥的地址
$builder->sign($signer, $keychain->getPrivateKey('file://{私钥地址}'));
$toekn = $builder->getToken();

验证token

秘钥解密

use Lcobucci\JWT\Signer\Hmac\Sha256;

$parse = (new Parser())->parse($token);
$signer = new Sha256();
$parse->verify($signer,'签名key');// 验证成功返回true 失败false

RSA和ECDSA

use Lcobucci\JWT\Signer\Rsa\Sha256;
use Lcobucci\JWT\Signer\Keychain;
$parse = (new Parser())->parse($token);
$signer = new Sha256();
var_dump($token->verify($signer, $keychain->getPublicKey('file://{公钥地址}'))

获取数据

因为数据部分可以直接获取到,不用解密。所以在验证token合法后直接读取即可,这也是不要在载体中存放敏感信息的原因。

$parse = (new Parser())->parse($token);
// 获取全部信息,返回一个数组,
var_dump($parse->getClaims());
// 获取单条信息
var_dump($parse->getClaim('aud'));
....

这里写图片描述

注意事项

关于jwt的使用大概就是这些。上面的代码在你使用的时候可能会出现两个问题:

1、命名空间错误 
解决:不使用命名空间的话,使用require引入文件。如果使用命名空间出现错误,请检查命名空间的路径。

2、生成的token是一个对象 
解决:(string)$token 将token强转成string

最后,如果上面写的有错误或者不足的地方,欢迎在下面留言给我。

实现JWT的RS256加密算法需要使用PHP的openssl扩展,以下是一个简单的示例代码: ```php <?php // 生成JWT Token function generateToken($payload, $privateKey) { // JWT 头部 $header = array( "alg" => "RS256", "typ" => "JWT" ); // JWT 载荷 $payload = json_encode($payload); // JWT 签名 $headerEncoded = base64UrlEncode(json_encode($header)); $payloadEncoded = base64UrlEncode($payload); $data = $headerEncoded . '.' . $payloadEncoded; $signature = ''; openssl_sign($data, $signature, $privateKey, OPENSSL_ALGO_SHA256); $signatureEncoded = base64UrlEncode($signature); // JWT Token $jwtToken = $headerEncoded . '.' . $payloadEncoded . '.' . $signatureEncoded; return $jwtToken; } // 验证JWT Token function verifyToken($jwtToken, $publicKey) { $jwtParts = explode('.', $jwtToken); if (count($jwtParts) != 3) { return false; } $headerEncoded = $jwtParts[0]; $payloadEncoded = $jwtParts[1]; $signatureEncoded = $jwtParts[2]; $header = json_decode(base64UrlDecode($headerEncoded), true); if (!isset($header['alg']) || $header['alg'] !== 'RS256') { return false; } $payload = json_decode(base64UrlDecode($payloadEncoded), true); if (!$payload) { return false; } $data = $headerEncoded . '.' . $payloadEncoded; $signature = base64UrlDecode($signatureEncoded); // 验证签名 $verifyResult = openssl_verify($data, $signature, $publicKey, OPENSSL_ALGO_SHA256); if ($verifyResult === 1) { return true; } else { return false; } } // Base64 URL 编码 function base64UrlEncode($data) { $urlsafe = strtr(base64_encode($data), '+/', '-_'); return rtrim($urlsafe, '='); } // Base64 URL 解码 function base64UrlDecode($data) { $data = strtr($data, '-_', '+/'); $dataLen = strlen($data) % 4; if ($dataLen) { $data .= str_repeat('=', 4 - $dataLen); } return base64_decode($data); } // 读取私钥 $privateKey = openssl_pkey_get_private("file://path/to/private_key.pem"); // 读取公钥 $publicKey = openssl_pkey_get_public("file://path/to/public_key.pem"); // 生成Token $payload = array( "sub" => "1234567890", "name" => "John Doe", "iat" => 1516239022 ); $jwtToken = generateToken($payload, $privateKey); echo "JWT Token: " . $jwtToken . "\n"; // 验证Token $verifyResult = verifyToken($jwtToken, $publicKey); if ($verifyResult) { echo "Token 验证成功\n"; } else { echo "Token 验证失败\n"; } ``` 在以上示例代码中,`generateToken` 函数用于生成JWT Token,`verifyToken` 函数用于验证JWT Token。`base64UrlEncode` 和 `base64UrlDecode` 分别用于进行Base64 URL编码和解码。请注意,需要将私钥和公钥保存在文件中,并且需要指定正确的文件路径。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值