ThinkPHP 集成 jwt 技术 token 验证

一、思路流程二、安装 firebase/php-jwt三、封装token类四、创建中间件,检验Token校验时效性五、配置路由中间件六、写几个测试方法,通过postman去验证

一、思路流程

客户端使用用户名和密码请求登录服务端收到请求,验证用户名和密码验证成功后,服务端会签发一个token,再把这个token返回给客户端客户端收到token后可以把它存储起来,比如放到cookie中客户端每次向服务端请求资源时需要携带服务端签发的token,可以在cookie或者header中携带服务端收到请求,然后去验证客户端请求里面带着的token,如果验证成功,就向客户端返回请求数据

二、安装 firebase/php-jwt

composer require firebase/php-jwt

三、封装token类

因为我这个是多应用,然后我就只在index应用(只提供api接口)下设置了token类

namespace app\index\server;

use Firebase\JWT\JWT;

use Firebase\JWT\Key;

class Token

{

protected $key;

public function __construct()

{

//从配置信息这种或取唯一字符串,你可以随便写比如md5('token')

$this->key = 'adcdefg';

}

/**

* 生成token

* @param $uid

* @return mixed

*/

function generateToken($uid)

{

//获取当前时间戳

$currentTime = time();

$data = array(

"iss" => $this->key, //签发者 可以为空

"aud" => '', //面象的用户,可以为空

"iat" => $currentTime, //签发时间

"nbf" => $currentTime, //立马生效

"exp" => $currentTime + 7200, //token 过期时间 两小时

"data" => [ //记录的userid的信息,这里是自已添加上去的,如果有其它信息,可以再添加数组的键值对

'uid' => $uid,

]

);

//生成token

$token = JWT::encode($data, $this->key, "HS256"); //根据参数生成了 token

return $token;

}

/**

* 校验token时效性

*/

public function chekToken($token)

{

$status=array("code"=>2);

try {

JWT::$leeway = 60;//当前时间减去60,把时间留点余地

$decoded = JWT::decode($token,new Key($this->key,'HS256')); //HS256方式,这里要和签发的时候对应

$arr = (array)$decoded;

$res['code']=1;

$res['data']=$arr['data'];

return $res;

} catch(\Firebase\JWT\SignatureInvalidException $e) { //签名不正确

$status['msg']="签名不正确";

return $status;

}catch(\Firebase\JWT\BeforeValidException $e) { // 签名在某个时间点之后才能用

$status['msg']="token失效";

return $status;

}catch(\Firebase\JWT\ExpiredException $e) { // token过期

$status['msg']="token失效";

return $status;

}catch(\Exception $e) { //其他错误

$status['msg']="未知错误";

return $status;

}

}

}

四、创建中间件,检验Token校验时效性

创建中间件命令:

php think make:middleware CheckToken

declare (strict_types = 1);

namespace app\middleware;

class CheckToken

{

/**

* 处理请求 token 验证

*

* @param \think\Request $request

* @param \Closure $next

* @return Response

*/

public function handle($request, \Closure $next)

{

//第一步先取token

$token = $request->header('token');

//jwt进行校验token

$res = (new TokenServer())->chekToken($token);

if ($res['code'] != 1 ){

return json(['error_code'=>999,'msg'=>$res['msg'],'data'=>''],400);

}

$request->uid = $res['data']->uid;

return $next($request);

}

}

五、配置路由中间件

在config/middleware.php中注册中间件

// 中间件配置

return [

// 别名或分组

'alias' => [

// 注册中间件

'check' => [

app\middleware\CheckToken::class

],

],

// 优先级设置,此数组中的中间件会按照数组中的顺序优先执行

'priority' => [],

];

在app/api/route/route.php路由文件中进行使用,进行使用中间件校验token

use think\facade\Route;

// restfull 资源路由

Route::resource('a', 'TestR');

// 路由分组

Route::group('a',function (){

})->middleware('check');

六、写几个测试方法,通过postman去验证

declare (strict_types = 1);

namespace app\index\controller;

use app\index\server\Token as TokenServer;

use think\Request;

use think\annotation\route\Resource;

// 资源控制器

/**

* @Resource("a")

*/

class TestR

{

/**

* 显示资源列表

*

* @return \think\Response

*/

public function index(Request $request)

{

// 假定用户名为robin和密码为123456即为正确的账号

if($request->param('uname') == 'robin'&& $request->param('upwd')=='123456')

{

$uid = $request->param('uname');

// 设置token

$token = (new TokenServer())->generateToken($uid);

$data = ['name' => 'thinkphp', 'status' => '1','token'=>$token];

// 给前端返回json字符串,同时前端将token获取并且存入到以后的所有操作中

return show(config("status.success"),"请求成功",$data);

}else{

return show(config("status.error"),"用户名密码错误",null);

}

}

/**

* 保存新建的资源

*

* @param \think\Request $request

* @return \think\Response

*/

public function save(Request $request)

{

// 用update 来验证一下token

$token = $request->param('token');

$rs = checkToken($token);

return json($rs);

}

// ....

}

模拟登录测试

模拟前端携带token参数访问

精彩内容

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。