Jwt的使用

Jwt的使用

在用户登录时,登录验证成功,使用Jwt生成该user_id的token,然后将该token返回给客户端,客户端存储起来,每次请求服务端时,将用户的token放在请求头中发送到服务端,服务端对该token做验证。

项目根目录使用composer安装jwt工具类

composer require lcobucci/jwt 3.3

service层封装Jwt功能方法。

<?php
/**
 * Created by PhpStorm.
 * User: wyq
 * Date: 2021/11/19
 * Time: 17:02
 */


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

class Jwt extends Base_Controller
{
    public function __construct()
    {
        parent::__construct();
    }
    //config
    private static $_config = [
        'audience' => 'http://www.ci.com',//接收人
        'id' => '3f2g57a92aa',//token的唯一标识,这里只是一个简单示例
        'sign' => 'iblog',//签名密钥
        'issuer' => 'http://ci.com',//签发人
        'expire' => 86400 //有效期一天
    ];

    //生成token
    public static function getToken($user_id){
        //签名对象
        $signer = new Sha256();
        //获取当前时间戳
        $time = time();
        //设置签发人、接收人、唯一标识、签发时间、立即生效、过期时间、用户id、签名
        $token = (new Builder())->issuedBy(self::$_config['issuer'])
            ->canOnlyBeUsedBy(self::$_config['audience'])
            ->identifiedBy(self::$_config['id'], true)
            ->issuedAt($time)
            ->canOnlyBeUsedAfter($time-1)
            ->expiresAt($time + self::$_config['expire'])
            ->with('user_id', $user_id)
            ->sign($signer, self::$_config['sign'])
            ->getToken();
        return (string)$token;
    }

    //从请求信息中获取token令牌
    public static function getRequestToken()
    {
        if (empty($_SERVER['HTTP_AUTHORIZATION'])) {
            return false;
        }

        $header = $_SERVER['HTTP_AUTHORIZATION'];
        $method = 'bearer';
        //去除token中可能存在的bearer标识
        return trim(str_ireplace($method, '', $header));
    }

    //从token中获取用户id (包含token的校验)
    public static function getUserId($token = null)
    {
        $user_id = null;

        $token = empty($token)?self::getRequestToken():$token;
        $token = (new Parser())->parse((string) $token);
        //验证token
        $data = new ValidationData();
        $data->setIssuer(self::$_config['issuer']);//验证的签发人
        $data->setAudience(self::$_config['audience']);//验证的接收人
        $data->setId(self::$_config['id']);//验证token标识

        if (!$token->validate($data)) {
            //token验证失败
            return $user_id;
        }

        //验证签名
        $signer = new Sha256();
        if (!$token->verify($signer, self::$_config['sign'])) {
            //签名验证失败
            return $user_id;
        }
        //从token中获取用户id
        $user_id = $token->getClaim('user_id');
    }
        return $user_id;
  }
}

修改.htaccess使得可以获取到请求头信息Authorization信息

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{HTTP:Authorization} ^(.+)$
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
    RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>
测试代码
public function test()
    {
    	//获取id为2的用户的token
        $userToken = $this->Jwt_service->getToken(2);
    	//获取当前请求头的token
        $token = $this->Jwt_service->getRequestToken();
    	//通过请求头token获取用户id
        $userId = $this->Jwt_service->getUserId($token);
		
        $data = [
            'userToken' => $userToken,	//id为2的用户token
            'token' => $token,			//从请求头获取的token
            'userId' => $userId,		//从token中获取用户id
        ];
        success($data);
    }

postman在请求头发送一个生成好的token,模拟客户端发送请求。

Jwt的使用

返回示例

{
    "code": 200,
    "msg": "success",
    "data": {
        "userToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImp0aSI6IjNmMmc1N2E5MmFhIn0.eyJpc3MiOiJodHRwOlwvXC9jaS5jb20iLCJhdWQiOiJodHRwOlwvXC93d3cucHlnLmNvbSIsImp0aSI6IjNmMmc1N2E5MmFhIiwiaWF0IjoxNjM3NjM5MzMwLCJuYmYiOjE2Mzc2MzkzMjksImV4cCI6MTYzNzcyNTczMCwidXNlcl9pZCI6Mn0.dZcgOW_VW5XSYbB5Aysda7bJjauYcG9qkHx3aanKuwg",
        "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImp0aSI6IjNmMmc1N2E5MmFhIn0.eyJpc3MiOiJodHRwOlwvXC9jaS5jb20iLCJhdWQiOiJodHRwOlwvXC93d3cucHlnLmNvbSIsImp0aSI6IjNmMmc1N2E5MmFhIiwiaWF0IjoxNjM3NTYwNTU5LCJuYmYiOjE2Mzc1NjA1NTgsImV4cCI6MTYzNzY0Njk1OSwidXNlcl9pZCI6MX0.TVp0BXol8gRRyLJivLAZWkZrAWsiB-pOuvUsHZ6_2Kc",
        "userId": 1
    }
}
上一篇:JWT有状态登陆与无状态登陆的区别


下一篇:关于JWT的登录写入