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 相关文章推荐
多重?l件?合查?(二)
Oct 09 PHP
PHP乱码问题,UTF-8乱码常见问题小结
Apr 09 PHP
PHP的变量类型和作用域详解
Mar 12 PHP
zf框架的db类select查询器join链表使用示例(zend框架)
Mar 14 PHP
Yii核心组件AssetManager原理分析
Dec 02 PHP
9个经典的PHP代码片段分享
Dec 18 PHP
php中JSON的使用与转换
Jan 14 PHP
PHP、Java des加密解密实例
Apr 27 PHP
php检测图片主要颜色的方法
Jul 01 PHP
php限制文件下载速度的代码
Oct 20 PHP
thinkPHP基于ajax实现的菜单与分页示例
Jul 12 PHP
yii插入数据库防并发的简单代码
May 27 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中实现进程间通讯
2006/10/09 PHP
php 进度条实现代码
2009/03/10 PHP
phpstrom使用xdebug配置方法
2013/12/17 PHP
两级联动select刷新后其值保持不变的实现方法
2014/01/27 PHP
php中获取主机名、协议及IP地址的方法
2014/11/18 PHP
windows下配置php5.5开发环境及开发扩展
2014/12/25 PHP
YII Framework框架教程之安全方案详解
2016/03/14 PHP
PHP水印类,支持添加图片、文字、填充颜色区域的实现
2017/02/04 PHP
php中bind_param()函数用法分析
2017/03/28 PHP
二行代码解决全部网页木马
2008/03/28 Javascript
jQuery的12招常用技巧分享
2011/08/08 Javascript
javascript实现日历控件(年月日关闭按钮)
2012/12/12 Javascript
一个JS的日期格式化算法示例
2013/07/31 Javascript
Jquery模仿Baidu、Google搜索时自动补充搜索结果提示
2013/12/26 Javascript
Node.js和PHP根据ip获取地理位置的方法
2014/03/14 Javascript
jQuery.holdReady()使用方法
2014/05/20 Javascript
ActiveX控件与Javascript之间的交互示例
2014/06/04 Javascript
Node.js的项目构建工具Grunt的安装与配置教程
2016/05/12 Javascript
JS常用字符串方法(推荐)
2021/01/15 Javascript
使用JS轻松实现ionic调用键盘搜索功能(超实用)
2016/09/06 Javascript
网站申请不到支付宝接口、微信接口,免接口收款实现方式几种解决办法
2016/12/14 Javascript
详解jQuery中的DOM操作
2016/12/23 Javascript
JS常见简单正则表达式验证功能小结【手机,地址,企业税号,金额,身份证等】
2017/01/22 Javascript
解决vue安装less报错Failed to compile with 1 errors的问题
2020/10/22 Javascript
[43:32]2014 DOTA2华西杯精英邀请赛 5 25 LGD VS NewBee第一场
2014/05/26 DOTA
Python中实现输入超时及如何通过变量获取变量名
2020/01/18 Python
Python使用xlrd实现读取合并单元格
2020/07/09 Python
国际鲜花速递专家:Floraqueen
2016/11/24 全球购物
阿迪达斯德国官方网站:adidas德国
2017/07/12 全球购物
澳大利亚购买最佳炊具品牌网站:Cookware Brands
2019/02/16 全球购物
你经历的项目中的SCM配置项主要有哪些?什么是配置项?
2013/11/04 面试题
八年级数学教学反思
2014/01/31 职场文书
2015财务年度工作总结范文
2015/05/04 职场文书
《秋天的雨》教学反思
2016/02/19 职场文书
话题作文之学会尊重
2019/12/16 职场文书