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 相关文章推荐
FCKeditor添加自定义按钮
Mar 27 PHP
php Session存储到Redis的方法
Nov 04 PHP
php导出csv格式数据并将数字转换成文本的思路以及代码分享
Jun 05 PHP
PHP OPP机制和模式简介(抽象类、接口和契约式编程)
Jun 09 PHP
phpmailer在服务器上不能正常发送邮件的解决办法
Jul 08 PHP
php使用递归计算文件夹大小
Dec 24 PHP
PHP实现在线阅读PDF文件的方法
Jun 17 PHP
PHP仿微信多图片预览上传实例代码
Sep 13 PHP
利用switch语句进行多选一判断的实例代码
Nov 14 PHP
php die()与exit()的区别实例详解
Dec 03 PHP
PHP封装curl的调用接口及常用函数详解
May 31 PHP
php如何利用pecl安装mongodb扩展详解
Jan 09 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三维数组去重(示例代码)
2013/11/26 PHP
php版微信返回用户text输入的方法
2016/11/14 PHP
php实现socket推送技术的示例
2017/12/20 PHP
JS实多级联动下拉菜单类,简单实现省市区联动菜单!
2007/05/03 Javascript
javascript 隔行换色函数代码
2010/10/24 Javascript
jquery获取节点名称
2015/04/26 Javascript
jQuery调用Webservice传递json数组的方法
2016/08/06 Javascript
javaScript如何跳出多重循环break、continue
2016/09/01 Javascript
vue教程之toast弹框全局调用示例详解
2020/08/24 Javascript
利用nginx + node在阿里云部署https的步骤详解
2017/12/19 Javascript
Vue.js 踩坑记之双向绑定
2018/05/03 Javascript
解决vue this.$forceUpdate() 处理页面刷新问题(v-for循环值刷新等)
2018/07/26 Javascript
vue自定义指令实现方法详解
2019/02/11 Javascript
微信小程序图片左右摆动效果详解
2019/07/13 Javascript
[02:04]2014DOTA2国际邀请赛 BBC小组赛第三天总结
2014/07/12 DOTA
[40:03]Liquid vs Optic 2018国际邀请赛淘汰赛BO3 第一场 8.21
2018/08/22 DOTA
Python中的魔法方法深入理解
2014/07/09 Python
Python中正则表达式的详细教程
2015/04/30 Python
Python基于pillow判断图片完整性的方法
2016/09/18 Python
Python实现屏幕截图的代码及函数详解
2016/10/01 Python
python中os和sys模块的区别与常用方法总结
2017/11/14 Python
Python编写一个优美的下载器
2018/04/15 Python
10 行 Python 代码教你自动发送短信(不想回复工作邮件妙招)
2018/10/11 Python
在django模板中实现超链接配置
2019/08/21 Python
Python协程操作之gevent(yield阻塞,greenlet),协程实现多任务(有规律的交替协作执行)用法详解
2019/10/14 Python
Python第三方库的几种安装方式(小结)
2020/04/03 Python
python读取配置文件方式(ini、yaml、xml)
2020/04/09 Python
Django项目在pycharm新建的步骤方法
2021/03/02 Python
美国在线和移动免费会员制批发零售商:Boxed(移动端的Costco)
2020/01/02 全球购物
某公司面试题
2012/03/05 面试题
护理学中专毕业生求职信
2013/11/11 职场文书
幼儿园运动会入场词
2014/02/10 职场文书
安全生产承诺书
2014/03/26 职场文书
第二批党的群众路线教育实践活动总结报告
2014/10/30 职场文书
2015年元旦晚会活动总结(学生会)
2014/11/28 职场文书
讲解MySQL增删改操作
2022/05/06 MySQL