PHP如何使用JWT做Api接口身份认证的实现


Posted in PHP onFebruary 03, 2020

1.JWT是什么?

JWT官网 https://jwt.io

官网简介:JSON Web令牌(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间作为JSON对象安全地传输信息。由于此信息是经过数字签名的,因此可以被验证和信任。可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对对JWT进行签名。
通常来说,JWT是一个由包含用户信息所生成的加密串,将生成的JWT加密串放入所有的请求head中,前端通过设定的秘钥加密参数,发送数据给后端,后端接收参数,按照设定的秘钥,同样加密接收参数,与前端加密参数做比对,保证请求有效并防止参数不被篡改。验证通过就进行相关的逻辑处理,否则请求算作无效请求。

2.为什么使用JWT?

传统互联网项目在实现保持登录状态、退出登录、接口请求等功能时会使用Session,但是众所周知Session数据在产生后会存储与服务器端,所以当用户量达到一定程度会相应影响到服务器的性能,且Session在前后端分离的项目中或是多服务器项目中的支持不是很好。但是Token不会产生这些问题,服务器端对Token只有生成和验证操作,不会存放数据,针对前后端分离的项目,包括手机APP和当前热门的小程序的支持都很不错,所以Token成为了用于验证的极好选择。

3.在项目中引入JWT扩展

composer require firebase/php-jwt

4.JWT具体使用步骤

在登录控制器中

$key = 'e10adc3949ba59abbe56e057f20f883e';//自定义秘钥,加密解密都需要用到
$time = time(); //当前时间
$token = [
  'iat' => $time, //签发时间
  'nbf' => $time, //(Not Before):某个时间点后才能访问,比如设置time+30,表示当前时间30秒后才能使用
  'data' => [
    'userid' => 1,
    'username' => 'zqw.xyz',
  ]];
$jwtToken = \Firebase\JWT\JWT::encode($token, $key);

登录成功后,将生成 token 返回给前端。前端记录该用户信息的 token ,将 token 放入 head,之后的请求中都需要 head 都需包含 token。

我们可以定义一个 AppID 和 AppSecret,同时告知前端。前端每次请求中携带 AppID ,请求参数加入一个必要参数 sign ,sign 是由所有请求参数拼接而成加密后的加密串。
注意: sign 参数值,需要加入 AppID 所需要对应 AppSecret,请求参数和后端约定相同排序规则,然后进行加密。

后端验证签名是否通过

$token = $request->instance()->header('token');
if(empty($token)){
  abort(0, 'token验证失败');
}
$appid = $request->param('appid');
if(empty($appid)){
  abort(0, 'appid验证失败');
}
$request_time = $request->param('request_time');
if(empty($request_time)){
  abort(0,'时间戳验证失败');
}
$random_number = $request->param('random_number');
if(empty($random_number)){
  abort(0,'数字验证失败');
}
//记录每次请求的uuid,如果uuid已存在,则该次请求无效。

$request_uuid = Db::name('request')->where('uuid',$random_number)->find();
if(count($request_uuid) > 1){
  abort(0,'请求无效');
}else{
  Db::name('request')->insert([
    'uuid' => $random_number,
    'add_time' => time(),
    'url' => $request->baseUrl(),
  ]);
}



$secret_type = [
  'appid1' => 'bd98e16b5eaf3e49fa2ecd3f9ee8f6ae',
  'appid2' => 'b7e23061042f2799180e41d94cdbf861',
];
$secret = $secret_type[$appid];
if(empty($random_number)){
  abort(0,'secret验证失败');
}
$sign = $request->param('sign');
if(empty($sign)){
  abort(0,'sign验证失败');
}

$all_obj['secret'] = $secret;
ksort($all_obj);
$sign_key = '';
foreach ($all_obj as $k => $v) {
  $sign_key .= $k.='='.$v.'&';
}
$sign_key = substr_replace($sign_key ,"", -1);
$md_sign = md5($sign_key);
if($sign !== $md_sign){
  abort(0,'签名验证失败');
}
注意: 为防止重复请求,建议由前端每次传入 uuid ,根据 uuid 请求是否重复。
6.验证通过后,进行相关的业务逻辑代码处理。

// 
$result = array(
  'status' => 1,
  'msg' => '获取成功',
  'result' => array(
  )
);
return json($result)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
PHP+DBM的同学录程序(3)
Oct 09 PHP
PHP Squid中可缓存的动态网页设计
Sep 17 PHP
PHP代码网站如何防范SQL注入漏洞攻击建议分享
Mar 01 PHP
探讨:array2xml和xml2array以及xml与array的互相转化
Jun 24 PHP
php防止sql注入之过滤分页参数实例
Nov 03 PHP
为PHP安装imagick时出现Cannot locate header file MagickWand.h错误的解决方法
Nov 03 PHP
php调用新浪短链接API的方法
Nov 08 PHP
PHP实现QQ空间自动回复说说的方法
Dec 02 PHP
使用JavaScript创建新样式表和新样式规则
Jun 14 PHP
PHP验证码无法显示的原因及解决办法
Aug 11 PHP
php获取微信共享收货地址的方法
Dec 21 PHP
php实现微信分享朋友链接功能
Feb 18 PHP
PHP7创建销毁session的实例方法
Feb 03 #PHP
PHP7创建COOKIE和销毁COOKIE的实例方法
Feb 03 #PHP
Laravel + Elasticsearch 实现中文搜索的方法
Feb 02 #PHP
php封装的page分页类完整实例代码
Feb 01 #PHP
PHP实现简单的协程任务调度demo示例
Feb 01 #PHP
PHP设计模式之组合模式定义与应用示例
Feb 01 #PHP
php实现的简单多进程服务器类完整示例
Feb 01 #PHP
You might like
详细介绍PHP应用提速面面观
2006/10/09 PHP
php中session过期时间设置及session回收机制介绍
2014/05/05 PHP
PHP5.3与5.5废弃与过期函数整理汇总
2014/07/10 PHP
php文件缓存类汇总
2014/11/21 PHP
PHP实现表单提交数据的验证处理功能【防SQL注入和XSS攻击等】
2017/07/21 PHP
让GoogleCode的SVN下的HTML文件在FireFox下正常显示.
2009/05/25 Javascript
javascript 面向对象的JavaScript类
2010/05/04 Javascript
浏览器解析js生成的html出现样式问题的解决方法
2012/04/16 Javascript
javascript操作css属性
2013/12/30 Javascript
JS二维数组的定义说明
2014/03/03 Javascript
基于NodeJS的前后端分离的思考与实践(二)模版探索
2014/09/26 NodeJs
JS实现带有抽屉效果的产品类网站多级导航菜单代码
2015/09/15 Javascript
jQuery事件与动画基础详解
2017/02/23 Javascript
vue2.0数据双向绑定与表单bootstrap+vue组件
2017/02/27 Javascript
JS仿JQuery选择器功能
2017/03/08 Javascript
浅谈angular.js跨域post解决方案
2017/08/30 Javascript
vue中vee validate表单校验的几种基本使用
2018/06/25 Javascript
jquery+ajax实现上传图片并显示上传进度功能【附php后台接收】
2019/06/06 jQuery
微信小程序swiper使用网络图片不显示问题解决
2019/12/13 Javascript
[01:59]翻天覆地,因你而变,7.20版本地图更新速览
2018/11/24 DOTA
Python实现解析Bit Torrent种子文件内容的方法
2017/08/29 Python
Numpy中的mask的使用
2018/07/21 Python
对numpy中的transpose和swapaxes函数详解
2018/08/02 Python
PyQt5实现画布小程序
2020/05/30 Python
python3中编码获取网页的实例方法
2020/11/16 Python
台湾良兴购物网:EcLife
2019/12/01 全球购物
介绍一下如何优化MySql
2016/12/20 面试题
公司开业庆典主持词
2014/03/21 职场文书
《沉香救母》教学反思
2014/04/19 职场文书
计算机应用应届生求职信
2014/07/12 职场文书
2014年国庆节活动总结
2014/08/26 职场文书
诉讼授权委托书
2014/10/15 职场文书
主持人开幕词
2015/01/29 职场文书
美德少年主要事迹材料
2015/11/04 职场文书
会议主持词通用版
2019/04/02 职场文书
导游词之云南丽江古城
2019/09/17 职场文书