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 提速工具eAccelerator 配置参数详解
May 16 PHP
php操作JSON格式数据的实现代码
Dec 24 PHP
PHP数据集构建JSON格式及新数组的方法
Nov 07 PHP
php实现上传图片生成缩略图示例
Apr 13 PHP
phpMyAdmin自动登录和取消自动登录的配置方法
May 12 PHP
在win7中搭建Linux+PHP 开发环境
Oct 08 PHP
PHP输出日历表代码实例
Mar 27 PHP
PHP基于cookie与session统计网站访问量并输出显示的方法
Jan 15 PHP
人脸识别测颜值、测脸龄、测相似度微信接口
Apr 07 PHP
PHP通过CURL实现定时任务的图片抓取功能示例
Oct 03 PHP
PHP定义字符串的四种方式详解
Feb 06 PHP
THINKPHP5分页数据对象处理过程解析
Oct 28 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实现Ftp用户的在线管理
2012/02/16 PHP
PHP Class&Object -- PHP 自排序二叉树的深入解析
2013/06/25 PHP
php读取excel文件的简单实例
2013/08/26 PHP
XRegExp 0.2: Now With Named Capture
2007/11/30 Javascript
使用jquery插件实现图片延迟加载技术详细说明
2011/03/12 Javascript
js获取php变量的实现代码
2013/08/10 Javascript
JavaScript中的类数组对象介绍
2014/12/30 Javascript
.NET微信公众号开发之创建自定义菜单
2015/07/16 Javascript
jQuery实现的简单分页示例
2016/06/01 Javascript
概述javascript在Google IE中的调试技巧
2016/11/24 Javascript
Vuex之理解state的用法实例
2017/04/19 Javascript
nginx配置React静态页面的方法教程
2017/11/03 Javascript
mockjs+vue页面直接展示数据的方法
2018/12/19 Javascript
Vue.js结合bootstrap前端实现分页和排序效果
2018/12/29 Javascript
JavaScript实现的滚动公告特效【基于jQuery】
2019/07/10 jQuery
详解vuex数据传输的两种方式及this.$store undefined的解决办法
2019/08/26 Javascript
在vue中使用cookie记住用户上次选择的实例(本次例子中为下拉框)
2020/09/11 Javascript
[02:11]DOTA2上海特级锦标赛主赛事第二日RECAP
2016/03/04 DOTA
python实现比较两段文本不同之处的方法
2015/05/30 Python
深入了解Python数据类型之列表
2016/06/24 Python
Python生成数字图片代码分享
2017/10/31 Python
Python IDLE清空窗口的实例
2018/06/25 Python
python协程之动态添加任务的方法
2019/02/19 Python
python使用 cx_Oracle 模块进行查询操作示例
2019/11/28 Python
python设置代理和添加镜像源的方法
2020/02/14 Python
Python线程threading模块用法详解
2020/02/26 Python
Python特殊属性property原理及使用方法解析
2020/10/09 Python
你正在寻找的CSS3 动画技术
2011/07/27 HTML / CSS
美国第一个网上卖鞋零售商:OnlineShoes.com
2017/09/24 全球购物
设计部经理的岗位职责
2013/11/16 职场文书
工厂保洁员岗位职责
2013/12/04 职场文书
平面设计专业大学生职业规划书
2014/03/12 职场文书
主持词开场白
2014/03/17 职场文书
应届生求职自荐信
2014/07/04 职场文书
2014年保险公司工作总结
2014/11/22 职场文书
纪检监察立案决定书
2015/06/24 职场文书