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 相关文章推荐
域名查询代码公布
Oct 09 PHP
php字符串截取中文截取2,单字节截取模式
Dec 10 PHP
PHP Ajax中文乱码问题解决方法
Feb 27 PHP
php图片处理:加水印、缩略图的实现(自定义函数:watermark、thumbnail)
Dec 02 PHP
php daddslashes()和 saddslashes()有哪些区别分析
Oct 26 PHP
destoon实现不同会员组公司名称显示不同的颜色的方法
Aug 22 PHP
PHP中使用Imagick读取pdf并生成png缩略图实例
Jan 21 PHP
PHP yii实现model添加默认值的方法(两种方法)
Nov 10 PHP
PHP设计模式之工厂模式实例总结
Sep 01 PHP
Laravel模型间关系设置分表的方法示例
Apr 21 PHP
PHP实现的多维数组去重操作示例
Jul 21 PHP
php高性能日志系统 seaslog 的安装与使用方法分析
Feb 29 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
长波知识介绍
2021/03/01 无线电
PHP 学习路线与时间表
2010/02/21 PHP
教你识别简单的免查杀PHP后门
2015/09/13 PHP
jQuery 树形结构的选择器
2010/02/15 Javascript
Javascript引用指针使用介绍
2012/11/07 Javascript
jquery定时滑出可最小化的底部提示层特效代码
2013/10/02 Javascript
12种不宜使用的Javascript语法整理
2013/11/04 Javascript
jquery对元素拖动排序示例
2014/01/16 Javascript
JS 使用for循环遍历子节点查找元素
2014/09/06 Javascript
网页中表单按回车就自动提交的问题的解决方案
2014/11/03 Javascript
jQuery制作简洁的多级联动Select下拉框
2014/12/23 Javascript
Angularjs制作简单的路由功能demo
2015/04/14 Javascript
jquery判断单选按钮radio是否选中的方法
2015/05/05 Javascript
JavaScript中的数组遍历forEach()与map()方法以及兼容写法介绍
2016/05/19 Javascript
如何解决IONIC页面底部被遮住无法向上滚动问题
2016/09/06 Javascript
JS实现重新加载当前页面
2016/11/29 Javascript
微信小程序 检查接口状态实例详解
2017/06/23 Javascript
一文搞懂ES6中的Map和Set
2019/05/20 Javascript
详解基于原生JS验证表单组件xy-form
2019/08/20 Javascript
微信小程序:报错(in promise) MiniProgramError
2020/10/30 Javascript
Python struct模块解析
2014/06/12 Python
python基于右递归解决八皇后问题的方法
2015/05/25 Python
基于python的Tkinter编写登陆注册界面
2017/06/30 Python
python matplotlib 在指定的两个点之间连线方法
2018/05/25 Python
Python数据持久化shelve模块用法分析
2018/06/29 Python
详解将Django部署到Centos7全攻略
2018/09/26 Python
Python colormap库的安装和使用详情
2020/10/06 Python
分享一个页面平滑滚动小技巧(推荐)
2019/10/23 HTML / CSS
物流专业大学生求职信范文
2013/10/28 职场文书
大学同学聚会邀请函
2014/01/29 职场文书
艺术学院毕业生自荐信
2014/07/05 职场文书
个人遵守党的政治纪律情况对照检查材料思想汇报
2014/09/25 职场文书
2014年仓库管理员工作总结
2014/11/18 职场文书
租车协议书
2015/01/27 职场文书
2015最新学生自我评价范文
2015/03/03 职场文书
如何解决springcloud feign 首次调用100%失败的问题
2021/06/23 Java/Android