什么是Token?简单的说就是app接口请求的凭证,有了这个token才可以成功请求app接口(这里不讨论没有设置token的app接口,故意抬杠转牛角尖的朋友请绕道)。
这里分享的是通过JWT生成token。
Json web token(JWT)是为了网络应用环境间传递声明而执行的一种基于JSON的开发标准(RFC 7519),该token被设计为紧凑且安全的,特别适用于分布式站点的单点登陆(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。
下面来介绍生成token的具体操作。
1、开发环境
wamp:php7.2.1+laravel框架
JWT版本:MINIMUM VERSION 3.0.0
项目host:laravel.app.com
2、jwt安装
这里采用composer方式安装jwt
打开windows系统的控制台切换到app接口项目根目录,或者用开发工具(这里用phpstorm)打开app接口项目,一次执行如下命令
composer require lcobucci/jwt composer dump-autoload
如果是phpstorm,在它的左下角有个终端调式工具,类似linux系统的终端,可以在这执行上面的两个命令。
3、接下来就可以码代码了
在 app 下新建一个如下目录 Common\Auth ,在Auth中新建 JwtAuth.php token操作类,token的生成、验证都是同个这个类来完成。
①token生成
<?php namespace App\Common\Auth; use Lcobucci\JWT\Builder; //我们的token就是通过Bulider生成的 use Lcobucci\JWT\Signer\Hmac\Sha256; //字符加密 class JwtAuth { //token属性 private $Token; //项目host private $iss = 'laravel.app.com'; //项目签名 private $aud = 'own_laravel_app'; //用户uid private $uid; //加密字段 private $secret= 'sdf*rd4&#'; //类句柄 private static $instance; /** * 实例化 */ public static function getInstance() { if (is_null(self::$instance)){ self::$instance = new self(); } return self::$instance; } /** * 防止被实例化 * JwtAuth constructor. */ private function __construct() { } /** * 防止被clone */ private function __clone() { // TODO: Implement __clone() method. } /** * 获取token * @return string */ public function getToken() { return (string)$this->Token; } /** * 设置token * @param $token * @return $this */ public function setToken($token) { $this->Token = $token; return $this; } /** * 设置用用户uid * @param $uid * @return $this */ public function setUid($uid) { $this->uid = $uid; return$this; } /** * JWT编码 * @return $this */ public function encode() { $time = time(); $this->Token = (new Builder())->setHeader('alg', 'HS256') ->setIssuer($this->iss) ->setAudience($this->aud) ->setExpiration($time + 3600) ->set('uid',$this->uid) ->sign(new Sha256(),$this->secret) ->getToken(); return $this; } }
这里的 JwtAuth 采用的是单例模式, 在一次的app接口请求中都是同一个用户。
②验证是否成功生成token
新建一个 JwtLoginController 控制器
<?php namespace App\Http\Controllers; use Illuminate\Routing\Controller as BaseController; use App\Http\Response\ResponseJson; use Illuminate\Http\Request; use App\Common\Auth\JwtAuth; class JwtLoginController extends BaseController { use ResponseJson; public function login(Request $request) { //接收用户名和用户密码参数 $username = $request->input('username'); $password = $request->input('password'); //在实际项目中 需要验证用户名和密码,验证成功返回 uid //这里是测试实验就直接给定一个uid来生成token了 $JwtAuth = JwtAuth::getInstance(); $token = $JwtAuth->setUid(1)->encode()->getToken(); return $this->jsonSuccessData([ 'token'=>$token ]); } }
然后把控制器 JwtLoginController 中的login方法注册到路由,为了方便实验就注册到get方法中吧:
然后浏览器请求login方法:http://laravel.app.com/login
如果浏览器返回的token值是以‘.’分割的三段Base64编码,说明我们的token生成成功了。
【附】在上面的例子中有一个 use ResponseJson ,这个是用trait写的一个json统一格式返回数据,避免每次返回数据都要先把数据转换一下。
ResponseJson 的位置及代码如下:
<?php namespace App\Http\Response; trait ResponseJson { /** * app接口出现业务异常时的返回 * @param $code * @param $message * @param array $data * @return false|string */ public function jsonData($code, $message, $data=[]) { return $this->jsonResponse($code, $message, $data); } /** * app接口请求成功时的返回 * @param array $data * @return false|string */ public function jsonSuccessData($data=[]) { return $this->jsonResponse(0, 'Success', $data); } /** * 返回一个json * @param $code * @param $message * @param $data * @return false|string */ private function jsonResponse($code, $message, $data) { $content = [ 'code' => $code, 'msg' => $message, 'data' => $data, ]; return json_encode($content); } }