php blob 输出_PHP开发APP接口之JWT鉴权

简介:在前后端分离的时代,使用PHP开发APP后台API(接口)是很多公司的选择。但是传统的PHP开发API没有系统的把PHP当做一个工程化的项目来开发,没有明确各个模块的职责,所以本期相对的提出了一种比较通用的PHP开发API的方式,简单的从API输入输出、API鉴权,业务异常处理等模块来描述API各个模块以及各个模块之间的关系。在最后,介绍了一个API实例,该实例串联了API的各个模块,让大家达到融汇贯通的效果。

630fe8397d0b89ce9a5a3207c9ff31a7.gif

5d1f1fe3fbe4fc0771a59c6ee017e950.png

环境:lnmp (采用laradock搭建)

框架:laravel6.*

参考:https://github.com/lcobucci/jwt/blob/3.3/README.md 65829a7521f8ab9fa77b6aba3ac5c8c8.gif

首先什么是JWT

6afcf74f3e62793b175e7b08668fbabd.png

Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

ce752211c1e321626d0ae8963f915ca2.gif 65829a7521f8ab9fa77b6aba3ac5c8c8.gif

下面进入代码实战环节:

composer require lcobucci/jwt
<?php namespace App\Common\Auth;use Lcobucci\JWT\Builder;use Lcobucci\JWT\Parser;use Lcobucci\JWT\Signer\Hmac\Sha256;use Lcobucci\JWT\Signer\Key;use Lcobucci\JWT\ValidationData;class JwtAuth{/**
     * @var
     */private $token;private $decodeToken;private $iss = 'laravel_base.test';private $aud = 'laravel_base_service';private $uid;private $secrect = 'asfshgeatg';private $signer = 'strines';private static $instance = null;//构造器私有化:禁止从类外部实例化private function __construct(){}//克隆方法私有化:禁止从外部克隆对象private function __clone(){}//因为用静态属性返回类实例,而只能在静态方法使用静态属性//所以必须创建一个静态方法来生成当前类的唯一实例public static function getInstance(){//检测当前类属性$instance是否已经保存了当前类的实例if (self::$instance == null) {//如果没有,则创建当前类的实例self::$instance = new self();
        }//如果已经有了当前类实例,就直接返回,不要重复创建类实例return self::$instance;
    }/**
     * @return string
     */public function getToken(){return (string)$this->token;
    }/**
     * @param $token
     * @return $this
     */public function setToken($token){$this->token = $token;return $this;
    }public function getUid(){return $this->uid;
    }/**
     * @param $uid
     * @return $this
     */public function setUid($uid){$this->uid = $uid;return $this;
    }/**
     * @return $this
     */public function encode(){
        $time = time();
        $signer = new Sha256();$this->token = (new Builder())->issuedBy($this->iss) // Configures the issuer (iss claim)
        ->permittedFor($this->aud) // Configures the audience (aud claim)
        ->identifiedBy($this->secrect, true) // Configures the id (jti claim), replicating as a header item
        ->issuedAt($time) // Configures the time that the token was issue (iat claim)
        ->canOnlyBeUsedAfter($time) // Configures the time that the token can be used (nbf claim)
        ->expiresAt($time + 3600) // Configures the expiration time of the token (exp claim)
        ->withClaim('uid', $this->uid) // Configures a new claim, called "uid"
        ->getToken($signer, new Key($this->signer)); // Retrieves the generated tokenreturn $this;
    }/**
     * @return \Lcobucci\JWT\Token
     */public function decode(){if (!$this->decodeToken)
        {$this->decodeToken = (new Parser())->parse((string) $this->token); // Parses from a string$this->uid = $this->decodeToken->getClaim('uid');
        }return $this->decodeToken;
    }/**
     * @return bool
     */public function verify(){
        $signer = new Sha256();
        $result = $this->decode()->verify($signer, $this->signer);return $result;
    }/**
     * @return bool
     */public function validate(){
        $data = new ValidationData(); // It will use the current time to validate (iat, nbf and exp)
        $data->setIssuer($this->iss);
        $data->setAudience($this->aud);
        $data->setId($this->secrect);return $this->decode()->validate($data);
    }
}
65829a7521f8ab9fa77b6aba3ac5c8c8.gif

接下来就可以在控制器中使用了,如:

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(){
        $jwtAuth = JwtAuth::getInstance();
        $token = $jwtAuth->setUid(2)->encode()->getToken();
        return $this->jsonSuccessResponse([
            'token' => $token
        ]);
    }
65829a7521f8ab9fa77b6aba3ac5c8c8.gif

访问接口每次都要携带token令牌,那么怎么验证呢?那就是laravel路由中间件,如:

4047cdab14c5084678f12907cc63d4c2.png

65829a7521f8ab9fa77b6aba3ac5c8c8.gif

中间件是这样实现的,如:

<?php namespace App\Http\Middleware;use App\Common\Auth\JwtAuth;use App\Common\Err\ApiErrDesc;use App\Exceptions\ApiException;use App\Http\Response\JsonResponse;use Closure;class JwtMiddleware{use JsonResponse;/**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */public function handle($request, Closure $next){
        $token = $request->header('token');if ($token)
        {
            $JwtAuth = JwtAuth::getInstance();
            $JwtAuth->setToken($token);if ($JwtAuth->validate() && $JwtAuth->verify())
            {return $next($request);
            }else
            {throw new ApiException(ApiErrDesc::ERR_TOKEN);
            }
        }else
        {throw new ApiException(ApiErrDesc::ERR_MISSTOKEN);
        }
    }
}
65829a7521f8ab9fa77b6aba3ac5c8c8.gif

路由是这样使用的,如:

Route::get('/login', 'Api\ApiController@index');

Route::middleware('jwt_auth')->namespace('Api')->group(function(){
    Route::get('show','ApiController@show')->name('api.login');
});
65829a7521f8ab9fa77b6aba3ac5c8c8.gif

有问题可以随时加作者微信交流

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值