php

lcobucci/jwt的安装和使用

2023-09-17

安装

composer require lcobucci/jwt 3.3

封装

<?php

/**

 * author: sanxiao

 * datetime: 2019/12/8 17:49

 */

namespace Framework;

use Carbon\Carbon;

use Lcobucci\JWT\Token;

use Lcobucci\JWT\Token\DataSet;

use Lcobucci\JWT\Validation\Constraint\SignedWith;

use Lcobucci\JWT\Builder;

use Lcobucci\JWT\Parser;

use Lcobucci\JWT\Signer\Hmac\Sha256;

use Lcobucci\JWT\Signer\Key;

class Jwt {

    protected $header = 'authorization';

    protected $prefix = 'bearer';

    /**

     * @var Key

     */

    private $sign_key;

    /**

     * @var Parser

     */

    private $parser;

    /**

     * @var Builder

     */

    private $builder;

    /**

     * @var Sha256

     */

    private $signer;

    public function __construct(Parser $parser, Builder $builder)

    {

        $secret = env('JWT_SECRET');

        if (!$secret || $secret == 'APP_KEY') {

            $secret = env('APP_KEY', 'sanxiao');

        }

        $this->sign_key = new Key($secret);

        $this->parser = $parser;

        $this->builder = $builder;

        $this->signer = new Sha256();

    }

    /**

     * 获取JWT

     * @param string $id ID

     * @param array $ext 扩展信息

     * @param Carbon $issuedAt 发行时间

     * @param int $ttl 过期时间

     * @return string jwt

     */

    public function getToken(string $id, array $ext = [], Carbon $issuedAt = null, int $ttl = null) : string

    {

        $issuedAt = $issuedAt ?? Carbon::now();

        $token_ttl = config('jwt.ttl', 86400);

        $ttl = $ttl ?? $token_ttl;

        $this->builder->issuedAt($issuedAt->toDateTimeImmutable())

            ->expiresAt($issuedAt->addSeconds($ttl)->toDateTimeImmutable())

            ->withClaim('id', $id);

        foreach ($ext as $key => $val) {

            $this->builder->withClaim($key, $val);

        }

        $token = $this->builder->getToken($this->signer, $this->sign_key);

        return $token->toString();

    }

    /**

     * 从头部获取匹配的JWT

     * @return mixed

     */

    public function parse()

    {

        $header = request()->header($this->header);

        if ($header && preg_match('/'.$this->prefix.'\s*(\S+)\b/i', $header, $matches)) {

            return $matches[1];

        } else {

            return false;

        }

    }

    /**

     * 检查Token并返回用户ID

     * @return bool|int

     */

    public function checkToken()

    {

        $headerToken = $this->parse();

        if (!$headerToken) {

            return false;

        }

        try {

            /** @var Token $curToken */

            $curToken = $this->parser->parse((string)$headerToken);

            $signedWith = new SignedWith($this->signer, $this->sign_key);

            $signedWith->assert($curToken);

        } catch (\Exception $e) {

            return false;

        }

        $flg = $curToken->isExpired(Carbon::now()->toDateTimeImmutable());

        if ($flg) {

            return false;

        }

        if ($curToken->claims()->has('id')) {

            $user_id = $curToken->claims()->get('id');

        } else {

            return false;

        }

        return $user_id;

    }

    /**

     * 获取扩展信息

     * @param string $jwt

     * @return DataSet

     */

    public function getClaims(string $jwt) : DataSet

    {

        $token = $this->parser->parse($jwt);

        return $token->claims();

    }

}

使用

//在控制器中//获取用户id  

$user_id = $this->getAuthId();

继承的 BaseController

abstract class BaseController extends Controller

{

    use AuthorizesRequests, DispatchesJobs;

    use Helper;

    /**

     * 获取授权用户ID

     */

    public function getAuthId() : int

    {

        return Hope::getLoginId();

    }

    /**

     * 是否登录

     * @return bool

     */

    public function isLogin() : bool

    {

        return !!$this->getAuthId();

    }

}

公共方法文件

public static function getLoginId(): int

    {

        $jwt = app(Jwt::class);

        $user_id = $jwt->checkToken();

        if ($user_id === false) {

            return 0;

        }

        return $user_id;

    }

当然以上的代码层次 hope.php 公共类文件所放的文件夹需要在 composer.josn 文件中自动加载。

例如:我习惯放在 framework 文件夹


"autoload": {

        "psr-4": {

            "App\\": "app/",

            "Framework\\": "framework/",

            "Database\\Factories\\": "database/factories/",

            "Database\\Seeders\\": "database/seeders/"

        }

    },