php接口数据安全解决方案(二)
前言
JWT是什么
JWT是json web token缩写。它将用户信息加密到token里,服务器不保存任何用户信息。服务器通过使用保存的密钥验证token的正确性,只要正确即通过验证。基于token的身份验证可以替代传统的cookie+session身份验证方法。
它定义了一种用于简洁,自包含的用于通信双方之间以 JSON 对象的形式安全传递信息的方法。JWT 可以使用 HMAC 算法或者是 RSA 的公钥密钥对进行签名。
本实例是使用github开源项目来实现,项目地址为
点击查看源jwt项目代码
怎么使用jwt项目?
- 1.阅读GitHub上项目文档说明
- 2.composer安装jwt(composer require lcobucci/jwt)
- 3.引用vendor中autoload.php文件实现jwt类自动加载
实例演示token签名并创建token
<?php
include "./vendor/autoload.php";
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Hmac\Sha256;
$time = time();
$token = (new Builder())->setHeader('alg','HS256')
//配置发行者
->setIssuer("jwtTest")
//配置Audience
->setAudience("php")
//配置令牌发出的时间(签发时间)
->setIssuedAt($time)
//配置令牌该时间之前不接收处理该Token
->setNotBefore($time+60)
//配置令牌到期的时间
->setExpiration($time + 7200)
//配置一个自定义uid声明
->set('uid',20)
//使用sha256进行签名,密钥为123456
->sign(new Sha256(),"123456")
//获取token
->getToken();
// echo $token;
//获取设置所有header头
$headers = $token->getHeaders();
//获取所有的配置
$claims = $token->getClaims();
$alg = $token->getHeader('alg');
$iss = $token->getClaim('iss');
$aud = $token->getClaim('aud');
$iat = $token->getClaim('iat');
$exp = $token->getClaim('exp');
$nbf = $token->getClaim('nbf');
$uid = $token->getClaim('uid');
echo "=====下面是设置的header头信息======<br/>";
echo "当前token的alg盐值为{$alg}<br/>";
echo "=====下面是所有配置信息<br/>";
echo "当前token的发行者是:{$iss}<br/>";
echo "当前token的Audience是:{$aud}<br/>";
echo "当前token的令牌发出时间是:{$iat}<br/>";
echo "当前token不接收处理的时间为:{$nbf}<br/>";
echo "当前token的到期时间:{$exp}<br/>";
echo "当前token的uid是:{$uid}<br/>";
echo "当前token字符串为:{$token}";
结果展示:
=====下面是设置的header头信息======
当前token的alg盐值为HS256
=====下面是所有配置信息
当前token的发行者是:jwtTest
当前token的Audience是:php
当前token的令牌发出时间是:1563246935
当前token不接收处理的时间为:1563246995
当前token的到期时间:1563254135
当前token的uid是:20
当前token字符串为:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqd3RUZXN0IiwiYXVkIjoicGhwIiwiaWF0IjoxNTYzMjQ2OTM1LCJuYmYiOjE1NjMyNDY5OTUsImV4cCI6MTU2MzI1NDEzNSwidWlkIjoyMH0.O8tscKPweCvSaXkOVbmhtEcsJ7BWRxRn9s_xXFstgsE
解析token并校验token合法性
<?php
include "./vendor/autoload.php";
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\ValidationData;
//解析token
$token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqd3RUZXN0IiwiYXVkIjoicGhwIiwiaWF0IjoxNTYzMjQ2Mjc4LCJuYmYiOjE1NjMyNDYzMzgsImV4cCI6MTU2MzI1MzQ3OCwidWlkIjoyMH0.1XSZW6aWrHplAlMPMpc1K5gKdpWYE7AMa6T7qhBTF30';
//解析后的token对象
$decodeToken = (new Parser())->parse((string) $token);
$uid = $decodeToken->getClaim('uid');
$exp = $decodeToken->getClaim('exp');
$time = time();
echo "当前时间为:{$time}<br/>";
$result = $decodeToken->verify(new Sha256(),"123456");
//对token进行发行者和audience的校验
$data = new ValidationData();
$data->setAudience("php");
$data->setIssuer("jwtTest");
$resultVali = $decodeToken->validate($data);
// print_r($resultVali);
//判断token签名和校验发行者是否合法
if($result && $resultVali){
//如果设置的token有效时间大于当前时间则表示token过期了
if($time>$exp){
echo "该token已经过期了<br/>";
}else{
echo "该token是合法的uid为:{$uid},过期时间为{$exp}<br/>";
}
}else{
echo "该token不合法签名错误或发行者不合法<br/>";
}
运行后结果为:
当前时间为:1563248373
该token是合法的uid为:20,过期时间为1563253478
类库封装管理jwt实例
<?php
include "./vendor/autoload.php";
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\ValidationData;
use Lcobucci\JWT\Claim\GreaterOrEqualsTo;
use Lcobucci\JWT\Token;
/**
* Class JwtAuth
* @package App\Library
* @desc jwt接口鉴权类处理
*/
class JwtAuth{
//jwt token
private $token;
/**
* @var 用户传递的decode token
*/
private $decodeToken;
private static $_instance;
private $iss = "jwtTest";
private $aud = "php";
private $uid;
private $serect = "123456";
private $exp;//token失效时间
const EXP = 60;//token有效时间一个月
/**
* JwtAuth constructor.
* 私有化construct方法
*/
private function __construct()
{
}
/**
* 私有化clone方法
*/
private function __clone()
{
// TODO: Implement __clone() method.
}
/**
* 获取jwtauth类实例化对象
*/
public static function getInstance(){
if(!(self::$_instance instanceof JwtAuth) ){
self::$_instance = new JwtAuth();
}
return self::$_instance;
}
/**
* 获取token
* @return string
*/
public function getToken(){
return (string)$this->token;
}
/**
* 设置token
* @param $token
* @return $this
*/
public function setToken($token){
$this->token = $token;
return $this;
}
/**
* 设置uid
* @param $uid
* @return $this
*/
public function setUid($uid){
$this->uid = $uid;
return $this;
}
/**
* 获取uid
* @return mixed
*/
public function getUid(){
return $this->uid;
}
/**
* 获取exp
* @return mixed
*/
public function getExp(){
return $this->exp;
}
/**
* 编码jwt token
*/
public function encode(){
$time = time();
$this->token = (new Builder())->setHeader('alg','HS256')
->setIssuer($this->iss)
->setAudience($this->aud)
->setIssuedAt($time)
->setExpiration($time + self::EXP)
->set('uid',$this->uid)
->sign(new Sha256(),$this->serect)
->getToken();
return $this;
}
/**
* 解析传递的token
* @return 用户传递的decode
*/
public function decode(){
if(!$this->decodeToken){
// Parses from a string
$this->decodeToken = (new Parser())->parse((string) $this->token);
$this->uid = $this->decodeToken->getClaim('uid');
$this->exp = $this->decodeToken->getClaim('exp');
// error_log('exp:'.$this->decodeToken->getClaim('exp'));
// error_log('uid:'.$this->decodeToken->getClaim('uid'));
}
return $this->decodeToken;
}
/**
* verify校验token signature串第三个字符串
* @return mixed
*/
public function verify(){
$result = $this->decode()->verify(new Sha256(),$this->serect);
return $result;
}
/**
* 校验传递的token是否有效,校验前两个字符串
* @return mixed
*/
public function validate(){
$data = new ValidationData();
$data->setAudience($this->aud);
$data->setIssuer($this->iss);
return $this->decode()->validate($data);
}
}
/*
@desc 模拟登录返回token
*/
$jwtAuth = JwtAuth::getInstance();
$uid = 20;
$token = $jwtAuth->setUid($uid)->encode()->getToken();
echo "当前已经为您生成最新token:{$token}<br/>";
/*
1.解析token
2.校验token签名是否合法
3.验证token发行者等信息是否合法
4.校验token是否过期
*/
$token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqd3RUZXN0IiwiYXVkIjoicGhwIiwiaWF0IjoxNTYzMjY4NjExLCJleHAiOjE1NjMyNjg2NzEsInVpZCI6MjB9.PeEA3xTE2lKl4YCYQ2cjHSNYsrJ24HRnW1-yKM-LgHc';
$jwtAuth2 = JwtAuth::getInstance();
$jwtAuth2->setToken($token);
if($jwtAuth2->validate() && $jwtAuth2->verify()){
//初始化用户id
$uid = $jwtAuth2->getUid();
$exp = $jwtAuth2->getExp();
echo "token合法,您当前的uid为:{$uid},当前时间戳为:".time()."token有效时间为:{$exp}<br/>";
}else{
echo "token校验失败,token签名不合法,或token发行者信息不合法<br/>";
}
演示结果为
当前已经为您生成最新token:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqd3RUZXN0IiwiYXVkIjoicGhwIiwiaWF0IjoxNTYzMjY4NjIzLCJleHAiOjE1NjMyNjg2ODMsInVpZCI6MjB9.BrsVElhVkTIq5xH3-JpvqvawNhDALb98VYZGbMTzWV8
token合法,您当前的uid为:20,当前时间戳为:1563268623token有效时间为:1563268671
当前已经为您生成最新token:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqd3RUZXN0IiwiYXVkIjoicGhwIiwiaWF0IjoxNTYzMjY4NzA1LCJleHAiOjE1NjMyNjg3NjUsInVpZCI6MjB9.juTM5iG8LNDid8Sp4jOjtHeTitaIB2WxZeW3GjnQrB0
token校验失败,token签名不合法,或token发行者信息不合法
php接口数据安全解决方案(二)的更多相关文章
- php接口数据安全解决方案(一)
前言 目录介绍 登录鉴权图 接口请求安全性校验整体流程图 代码展示 演示用户登录 演示获取用户信息 文章完整代码地址 后记 前言 目的: 1.实现前后端代码分离,分布式部署 2.利用token替代se ...
- Oracle数据安全解决方案(1)——透明数据加密TDE
Oracle数据安全解决方案(1)——透明数据加密TDE2009年09月23日 22:49:00 华仔爱技术 阅读数:7991原文地址: http://www.oracle.com/technolog ...
- C#中抽象类和接口的区别(二)
一.抽象类: 抽象类是特殊的类,只是不能被实例化:除此以外,具有类的其他特性:重要的是抽象类可以包括抽象方法,这是普通类所不能的.抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们.另外 ...
- Mycat高可用解决方案二(主从复制)
Mycat高可用解决方案二(主从复制) 系统部署规划 名称 IP 主机名称 用户名/密码 配置 mysql主节点 192.168.199.110 mysql-01 root/hadoop 2核/2G ...
- 数字麦克风PDM信号采集与STM32 I2S接口应用(二)
在使用STM32的数字麦克风I2S接口时,计算采样率让人头疼,芯片手册上没有明确的说法,而手册上的计算方法经过测试确和实验不符.借助搜索引擎,大部分资料都是来自于开发板卖家或开发板论坛,主要是咪头采集 ...
- Sentry 企业级数据安全解决方案 - Relay 运行模式
内容整理自官方开发文档 Relay 可以在几种主要模式之一下运行,如果您正在配置 Relay server 而不是使用默认设置,那么事先了解这些模式至关重要. 模式存储在配置文件中,该文件包含 rel ...
- Sentry 企业级数据安全解决方案 - Relay 配置选项
Relay 的配置记录在文件 .relay/config.yml 中.要更改此位置,请将 --config 选项传递给任何 Relay 命令: ❯ ./relay run --config /path ...
- Sentry 企业级数据安全解决方案 - Relay 监控 & 指标收集
内容整理自官方文档 系列 Sentry 企业级数据安全解决方案 - Relay 入门 Sentry 企业级数据安全解决方案 - Relay 运行模式 Sentry 企业级数据安全解决方案 - Rela ...
- Sentry 企业级数据安全解决方案 - Relay 项目配置
内容整理自官方文档 系列 Sentry 企业级数据安全解决方案 - Relay 入门 Sentry 企业级数据安全解决方案 - Relay 运行模式 Sentry 企业级数据安全解决方案 - Rela ...
随机推荐
- linux服务脚本编写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...
- Win10《芒果TV》商店版更新v3.7.0卡牌版:为小冰生日献礼,为秋季创意者更新铺路
由宇宙跨物种新晋主持微软小冰和绍刚叔联袂主持的中国首档原创顶尖科技秀<我是未来>正在芒果台热播,Win10版<芒果TV>更新v3.7.0卡牌版,为微软小冰9月17日生日献礼. ...
- 利用NPOI生成DOCX文档
首先安装NPOI控件: Install-Package NPOI 代码: using NPOI.OpenXmlFormats.Wordprocessing; using NPOI.XWPF.UserM ...
- 如何使用C#创建Windows Webcam应用
原文:如何使用C#创建Windows Webcam应用 最近想用C#写一个camera的应用.搜索了Google和StackOverflow,发现大部分的sample用了WIA或者DirectShow ...
- Play Framework 模板里使用注入访问数据层
从Play2.4开始,推荐使用依赖注入替代静态控制器.因此我们不能像play2.3那样,在模板里直接调用object访问数据层.是的,我们还是可以使用常规方式,通过传参到模板里.不过这样很多时候不方便 ...
- 更换Qt QtEmbedded库的版本出现问题及解决(交叉编译OpenSSL)
近日将QtEmbedded库的版本由4.7.0更新到4.7.4.工具链并未改变,仍为 Target: arm-none-linux-gnueabiConfigured with: ......Thre ...
- layer 1.9.2 发布,国产 Web 弹层不懈的前行者
快速使用Romanysoft LAB的技术实现 HTML 开发Mac OS App,并销售到苹果应用商店中. <HTML开发Mac OS App 视频教程> 土豆网同步更新:http: ...
- WPF四年,尤不足以替代WinForm
WPF四年,尤不足以替代WinForm WPF出山已四年,作为官方内定的下一代UI系统掌门,没少露脸.但这个新掌门能否胜任,仍是众多开发者的心头之虑.通过对VisualStudio 2010的编辑器部 ...
- Qt之OpenSSL(有pro文件的路径格式,以及对libeay32和ssleay32的引用)
简述 OpenSSL是一个强大的安全套接字层密码库,囊括主要的密码算法.常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用. 简述 下载安装 使用 更多参考 下载安装 ...
- 每天进步一点--WCF学习笔记
最近买了一本书WCF服务编程,重头再开始了解学习WCF,现将学习记录,以便后来复习,也希望和大家一起进步. WCF用终结点表示一种组成关系,终结点就是地址.契约与绑定的混合品,即 地址(Address ...