前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PHP如何创建和管理JWT令牌

PHP如何创建和管理JWT令牌

作者头像
Tinywan
发布2024-04-15 10:55:26
1020
发布2024-04-15 10:55:26
举报
文章被收录于专栏:开源技术小栈开源技术小栈

JSON Web令牌(JWT)已成为Web开发中各方之间安全传输信息的流行方法。在本指南中,我们将探索在PHP中创建、验证和解码JWT令牌,而不依赖于外部库。我们将利用 hash_hmac 生成签名,利用 base64_encode/decode 进行编码和解码。

环境配置

在深入研究代码之前,请确保您的服务器上安装了PHP。此外,您可能希望使用Composer来管理依赖项。在这个例子中,我们将创建一个独立的类来处理JWT操作。

代码语言:javascript
复制
composer init
composer require guzzlehttp/guzzle

JWT 类

现在,让我们创建一个名为 Jwt 的类来封装JWT操作:

代码语言:javascript
复制
<?php
class Jwt
{
    /**string */
    private string $secretKey;
    
    /**
     * @param string $secretKey
     * @author Tinywan(ShaoBo Wan)
     */
    public function __construct(string $secretKey)
    {
        $this->secretKey = $secretKey;
    }

    /**
     * @desc create token
     * @param array $payload
     * @return string
     * @author Tinywan(ShaoBo Wan)
     */
    public function createToken(array $payload): string
    {
        // Implementation for creating JWT
    }
    
    /**
     * @desc validate token
     * @param string $token
     * @return bool
     * @author Tinywan(ShaoBo Wan)
    */
    public function validateToken(string $token): bool
    {
        // Implementation for validating JWT
    }
    
    /**
     * @desc decode token
     * @param string $token
     * @return array
     * @author Tinywan(ShaoBo Wan)
    */
    public function decodeToken(string $token): array
    {
        // Implementation for decoding JWT
    }
    // Helper functions for base64 URL encoding/decoding
}

创建JWT

让我们实现用于生成JWT的 createToken 方法:

代码语言:javascript
复制
/**
 * @desc create token
 * @param array $payload
 * @return string
 * @author Tinywan(ShaoBo Wan)
 */
public function createToken(array $payload): string
{
    $base64UrlHeader = $this->base64UrlEncode(json_encode(["alg" => "HS256", "typ" => "JWT"]));
    $base64UrlPayload = $this->base64UrlEncode(json_encode($payload));
    $base64UrlSignature = hash_hmac('sha256', $base64UrlHeader . '.' . $base64UrlPayload, $this->secretKey, true);
    $base64UrlSignature = $this->base64UrlEncode($base64UrlSignature);
    return $base64UrlHeader . '.' . $base64UrlPayload . '.' . $base64UrlSignature;
}

/**
 * @desc base64_encode 编码
 * @param string $data
 * @return string
 * @author Tinywan(ShaoBo Wan)
 */
private function base64UrlEncode(string $data): string
{
    $base64 = base64_encode($data);
    $base64Url = strtr($base64, '+/', '-_');
    return rtrim($base64Url, '=');
}

/**
 * @desc base64_encode 解码
 * @param string $data
 * @return string
 * @author Tinywan(ShaoBo Wan)
 */
private function base64UrlDecode(string $data): string
{
    $base64 = strtr($data, '-_', '+/');
    $base64Padded = str_pad($base64, strlen($base64) % 4, '=', STR_PAD_RIGHT);
    return base64_decode($base64Padded);
}

验证JWT

现在,让我们实现用于验证JWT的 validateToken 方法:

代码语言:javascript
复制
/**
 * @desc validate token
 * @param string $token
 * @return bool
 * @author Tinywan(ShaoBo Wan)
 */
public function validateToken(string $token): bool
{
    list($base64UrlHeader, $base64UrlPayload, $base64UrlSignature) = explode('.', $token);
    $signature = $this->base64UrlDecode($base64UrlSignature);
    $expectedSignature = hash_hmac('sha256', $base64UrlHeader . '.' . $base64UrlPayload, $this->secretKey, true);

    return hash_equals($signature, $expectedSignature);
}

解码JWT

最后,让我们实现用于解码JWT的 decodeToken 方法:

代码语言:javascript
复制
/**
 * @desc decode token
 * @param string $token
 * @return array
 * @author Tinywan(ShaoBo Wan)
 */
public function decodeToken(string $token): array
{
    list(, $base64UrlPayload, ) = explode('.', $token);
    $payload = $this->base64UrlDecode($base64UrlPayload);
    return json_decode($payload, true);
}

验证

代码语言:javascript
复制
<?php

require 'vendor/autoload.php';

// Your secret key (keep this secure)
$secretKey = 'Tinywan2024040000011';

// Create an instance of Jwt
$jwt = new \Tinywan\Jwt($secretKey);

// Create a JWT
$payload = [
    "user_id" => 2024,
    "username" => "Tinywan",
    "exp" => time() + 3600, // Token expiration time (1 hour)
];
$token = $jwt->createToken($payload);

echo 'JWT Token: ' . $token . PHP_EOL;

// Validate and decode the JWT
if ($jwt->validateToken($token)) {
    echo 'JWT is valid.' . PHP_EOL;
    $decodedPayload = $jwt->decodeToken($token);
    echo "Decoded Payload: " . json_encode($decodedPayload, JSON_PRETTY_PRINT).PHP_EOL;
    var_dump(json_decode(json_encode($decodedPayload), true));
} else {
    echo 'JWT is invalid.' . PHP_EOL;
}

输出

代码语言:javascript
复制
JWT Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoyMDI0LCJ1c2VybmFtZSI6IlRpbnl3YW4iLCJleHAiOjE3MTI1ODcyNTN9.7agfeUJxj-iE0oevkf_lQwmYZOcCd7ORHWycDNv27_I
JWT is valid.
Decoded Payload: {
    "user_id": 2024,
    "username": "Tinywan",
    "exp": 1712587253
}
array(3) {
  ["user_id"]=>
  int(2024)
  ["username"]=>
  string(7) "Tinywan"
  ["exp"]=>
  int(1712587253)
}

在本例中,我们创建了一个JWT,其有效负载包含用户ID、用户名和过期时间。然后我们使用我们的 Jwt类验证和解码JWT。

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-04-10,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 开源技术小栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 环境配置
  • JWT 类
  • 创建JWT
  • 验证JWT
  • 解码JWT
  • 验证
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com