Json Web Token(JWT)的使用

编辑于 2023-04-02 11:48 阅读 983

JWT 用于生成token,token里面可以包含用户信息,下面介绍两种php的实现方法

借助 composer 库

composer require firebase/php-jwt

生成token

<?php
require_once __DIR__ . '/../vendor/autoload.php';
use Firebase\JWT\JWT;

$key = 'abc';//app key
$payload = [
    'iss' => 'http://example.org',
    'aud' => 'http://example.com',
    'iat' => 1356999524,
    'nbf' => 1357000000
];

$token = JWT::encode($payload, $key, 'HS256');
echo $token.PHP_EOL;

传递token

上一步生成了token,前端拿到后,在访问需要鉴权的接口时,通过header传给后端,类似这样

Authorization: Bearer <token>

验证token

<?php
require_once __DIR__ . '/../vendor/autoload.php';
use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$key = 'abc';//app key
$token = '前端传过来的token'
$decoded = JWT::decode($token, new Key($key, 'HS256'));
print_r($decoded);

手动实现

生成token

<?php
$key = 'abc';//app key
$payload = [
    'iss' => 'http://example.org',
    'aud' => 'http://example.com',
    'iat' => 1356999524,
    'nbf' => 1357000000
];
$base64header=base64UrlEncode(json_encode(['typ'=>'JWT', 'alg'=>'HS256'], JSON_UNESCAPED_SLASHES));
$base64payload=base64UrlEncode(json_encode($payload, JSON_UNESCAPED_SLASHES));
echo $token=$base64header.'.'.$base64payload.'.'.signature($base64header, $base64payload, $key);
echo PHP_EOL;

function signature(string $base64header, string $base64payload, string $key){
    return base64UrlEncode(hash_hmac('sha256',
        $base64header.
        '.'.
        $base64payload,
        $key,true));
}

function base64UrlEncode(string $input) {
    return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
}

验证token

list($base64header, $base64payload, $sign) = explode('.', $token);
//签名验证
if (signature($base64header, $base64payload, $key)!==$sign) die('validation failure');

$payload = json_decode(base64UrlDecode($base64payload), JSON_OBJECT_AS_ARRAY);
var_dump($payload);

function signature(string $base64header, string $base64payload, string $key){
    return base64UrlEncode(hash_hmac('sha256',
        $base64header.
        '.'.
        $base64payload,
        $key,true));
}
function base64UrlDecode(string $input) {
    $remainder = strlen($input) % 4;
    if ($remainder) {
        $addlen = 4 - $remainder;
        $input .= str_repeat('=', $addlen);
    }
    return base64_decode(strtr($input, '-_', '+/'));
}

为什么相同的一组数据你生成的token和别人的不一样?

  • 你用的是['alg'=>'HS256', 'typ'=>'JWT'],他用的是['typ'=>'JWT', 'alg'=>'HS256']
  • 你用的是json_encode([], JSON_UNESCAPED_UNICODE),他用的是json_encode([], JSON_UNESCAPED_SLASHES)

参考

https://jwt.io

https://github.com/firebase/php-jwt

https://www.h5w3.com/223863.html

https://www.jianshu.com/p/a2efb2c8dcde

https://blog.csdn.net/wnvalentin/article/details/123802484

广而告之,我的新作品《语音助手》上架Google Play了,欢迎下载体验