没有Firebase JWT的JSON网络令牌功能类
php  /  管理员 发布于 3年前   617
我已经创建了一些关于如何使用 Firebase JWT 创建和使用 JSON Web 令牌的教程,但我决定尝试在没有框架的情况下只使用 PHP。
在本文中,您可以看到我如何创建自己的简单 JWT 生成器。
创建class
class JWT {
private $headers;
private $secret;
public function __construct()
{
$this->headers = [
'alg' => 'HS256', // we are using a SHA256 algorithm
'typ' => 'JWT', // JWT type
'iss' => 'jwt.local', // token issuer
'aud' => 'example.com' // token audience
];
$this->secret = 'thisIsASecret';
}
}
生成令牌
在这个类中,我们将创建我们的生成函数。
此函数将生成用于验证器的令牌。
public function generate(array $payload): string
{
$headers = $this->encode(json_encode($this->headers)); // encode headers
$payload["exp"] = time() + 60; // add expiration to payload
$payload = $this->encode(json_encode($payload)); // encode payload
$signature = hash_hmac('SHA256', "$headers.$payload", $this->secret, true); // create SHA256 signature
$signature = $this->encode($signature); // encode signature
return "$headers.$payload.$signature";
}
在我们的 generate 函数中,我们引用了一个 encode 函数。
此函数将简单地对令牌使用的字符串进行 base64 编码。
private function encode(string $str): string
{
return rtrim(strtr(base64_encode($str), '+/', '-_'), '='); // base64 encode string
}
验证我们的令牌
在这个函数中,我们获取生成的令牌,并验证字符串、编码,最后是时间。
我将它设置为 1 分钟,因此令牌将在 1 分钟后过期以确保它用于某个目的。
public function is_valid(string $jwt): bool
{
$token = explode('.', $jwt); // explode token based on JWT breaks
if (!isset($token[1]) && !isset($token[2])) {
return false; // fails if the header and payload is not set
}
$headers = base64_decode($token[0]); // decode header, create variable
$payload = base64_decode($token[1]); // decode payload, create variable
$clientSignature = $token[2]; // create variable for signature
if (!json_decode($payload)) {
return false; // fails if payload does not decode
}
if ((json_decode($payload)->exp - time()) < 0) {
return false; // fails if expiration is greater than 0, setup for 1 minute
}
if (isset(json_decode($payload)->iss)) {
if (json_decode($headers)->iss != json_decode($payload)->iss) {
return false; // fails if issuers are not the same
}
} else {
return false; // fails if issuer is not set
}
if (isset(json_decode($payload)->aud)) {
if (json_decode($headers)->aud != json_decode($payload)->aud) {
return false; // fails if audiences are not the same
}
} else {
return false; // fails if audience is not set
}
$base64_header = $this->encode($headers);
$base64_payload = $this->encode($payload);
$signature = hash_hmac('SHA256', $base64_header . "." . $base64_payload, $this->secret, true);
$base64_signature = $this->encode($signature);
return ($base64_signature === $clientSignature);
}
class完整示例代码:
class JWT
{
private $headers;
private $secret;
public function __construct()
{
$this->headers = [
'alg' => 'HS256', // we are using a SHA256 algorithm
'typ' => 'JWT', // JWT type
'iss' => 'jwt.local', // token issuer
'aud' => 'example.com' // token audience
];
$this->secret = 'thisIsASecret'; // change this to your secret code
}
public function generate(array $payload): string
{
$headers = $this->encode(json_encode($this->headers)); // encode headers
$payload["exp"] = time() + 60; // add expiration to payload
$payload = $this->encode(json_encode($payload)); // encode payload
$signature = hash_hmac('SHA256', "$headers.$payload", $this->secret, true); // create SHA256 signature
$signature = $this->encode($signature); // encode signature
return "$headers.$payload.$signature";
}
private function encode(string $str): string
{
return rtrim(strtr(base64_encode($str), '+/', '-_'), '='); // base64 encode string
}
public function is_valid(string $jwt): bool
{
$token = explode('.', $jwt); // explode token based on JWT breaks
if (!isset($token[1]) && !isset($token[2])) {
return false; // fails if the header and payload is not set
}
$headers = base64_decode($token[0]); // decode header, create variable
$payload = base64_decode($token[1]); // decode payload, create variable
$clientSignature = $token[2]; // create variable for signature
if (!json_decode($payload)) {
return false; // fails if payload does not decode
}
if ((json_decode($payload)->exp - time()) < 0) {
return false; // fails if expiration is greater than 0, setup for 1 minute
}
if (isset(json_decode($payload)->iss)) {
if (json_decode($headers)->iss != json_decode($payload)->iss) {
return false; // fails if issuers are not the same
}
} else {
return false; // fails if issuer is not set
}
if (isset(json_decode($payload)->aud)) {
if (json_decode($headers)->aud != json_decode($payload)->aud) {
return false; // fails if audiences are not the same
}
} else {
return false; // fails if audience is not set
}
$base64_header = $this->encode($headers);
$base64_payload = $this->encode($payload);
$signature = hash_hmac('SHA256', $base64_header . "." . $base64_payload, $this->secret, true);
$base64_signature = $this->encode($signature);
return ($base64_signature === $clientSignature);
}
}
结论
这是一个简单的项目,但按预期工作。
我过去使用过 Firebase JWT,但有时您只需要一个简单的解决方案,而无需导入整个库。
我希望这对您的下一个小项目有所帮助。您可以在我的 GitHub 上下载该课程或在 YouTube 上订阅更多教程。
转:
https://dev.to/thedevdrawer/json-web-tokens-without-firebase-jwt-3mop
122 在
学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
Copyright·© 2019 侯体宗版权所有·
粤ICP备20027696号