php实现jwt签名、验证

时间:2019-07-06作者:klpeng分类:IT综合浏览:2025评论:0

composer下有个包,可以用来实现jwt,我们重新包装下拿来用。

1、安装composer包

composer require firebase/php-jwt

2、编写一个JwtService的类

<?php

use Firebase\JWT\JWT;

class JwtService
{

    private $key;

    public function __construct()
    {
        $this->key = '123456'; //这个秘钥需要保护好,生产环境建议配置化,不要硬编码到代码里。
    }

    public function getToken($data)
    {
        $domain = $_SERVER['SERVER_NAME'];
        $key    = $this->key; //key
        $time   = time(); //当前时间
        $token  = [
            'iss'  => $domain, //签发者 可选
            'aud'  => $domain, //接收该JWT的一方,可选
            'iat'  => $time, //签发时间
            'nbf'  => $time, //(Not Before):某个时间点后才能访问,比如设置time+30,表示当前时间30秒后才能使用
            'exp'  => $time + 3600 * 24 * 10, //过期时间,这里设置10天,这里也可以配置化处理
            'data' => $data, //自定义信息,不要定义敏感信息,一般放用户id,足以。
        ];

        return JWT::encode($token, $key); //输出Token
    }

    /**
     * 校验jwt权限API
     * @return [type] [description]
     */
    public function checkToken()
    {
        if (!isset($_SERVER['HTTP_AUTHORIZATION'])) {
            return 'token不存在,请重新登录!';
        }

        $jwt = $_SERVER['HTTP_AUTHORIZATION'];

        $key = $this->key;
        try {
            JWT::$leeway = 60; //当前时间减去60,把时间留点余地
            $decoded     = JWT::decode($jwt, $key, ['HS256']); //HS256方式,这里要和签发的时候对应
            $arr         = (array) $decoded;
        } catch (\Exception $e) {
            //Firebase定义了多个 throw new,我们可以捕获多个catch来定义问题,catch加入自己的业务,比如token过期可以用当前Token刷新一个新Token
            return $e->getMessage();
        }

        return (array) $arr['data'];
    }
}

3、测试,一般jwt使用分两步走,

一步是签名下发到客户端,login.php

<?php
require './vendor/autoload.php';
require './JwtService.php';

//用户发送账号密码过来,验证过后,就签发秘钥

$jwt  = new JwtService();
$uid  = 1;
$data = ['uid' => $uid];

$res = $jwt->getToken($data);

echo json_encode(['token' => $res, 'status' => 0]);

另外一步就是客户端拿到了签名数据,下次请求就带着这个签名数据过来服务器端,服务器端得到后,就开始验签。index.php

<?php
require './vendor/autoload.php';
require './JwtService.php';

$jwt = new JwtService();

$res = $jwt->checkToken();

if (is_array($res)) {
    echo "用戶UID" . $res['uid'];
} else {
    echo "错误!";
}

jwt相较于session,各自有自己的特点,开发的时候,应该根据实际的场景使用不同的机制来验证客户端的身份。

jwt的缺点,下发的签名一旦给了客户端,除了过期,就无法主动剔除,需要自己在代码逻辑重新处理。

还有就是为了避免签名被盗,强烈建议使用https,都什么时代了,还是用http,网络安全不可忽视啊。

打赏
文章版权声明:除非注明,否则均为彭超的博客原创文章,转载或复制请以超链接形式并注明出处。
相关推荐

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

猜你喜欢