lcobucci/jwt的安裝和使用(讓天下沒有難寫和難讀的程式碼)

SanXiao發表於2021-12-18
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();
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/"
        }
    },
本作品採用《CC 協議》,轉載必須註明作者和本文連結
過去心不可得,現在心不可得,未來心不可得

相關文章