什么是JWTJWT(json web token)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。

JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。比如用在用户登录上。

JWT定义了一种用于简洁,自包含的用于通信双方之间以 JSON 对象的形式安全传递信息的方法。JWT 可以使用 HMAC 算法或者是 RSA 的公钥密钥对进行签名。

JWT有两个特点:

自包含(Self-contained):负载中包含了所有用户所需要的信息,避免了多次查询数据库

简洁(Compact):可以通过URL, POST 参数或者在 HTTP header 发送,因为数据量小,传输速度快

JWT组成

JWT由header,payload,signature三个部分,下面我们用官网的实例先来讲解一个这三个部分的用法。

header部分:

jwt的头部承载两部分信息:

声明类型,这里是jwt

声明加密的算法 通常直接使用 HMAC SHA256

完整的头部就像下面这样的JSON:

{"alg": "HS256","typ": "JWT"
}

对应base64UrlEncode编码为:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

说明:该字段为json格式。alg字段指定了生成signature的算法,默认值为HS256,typ默认值为JWT

payload部分:

载荷就是存放有效信息的地方。

标准中注册的声明 (建议但不强制使用) :

iss: jwt签发者

sub: jwt所面向的用户

aud: 接收jwt的一方

exp: jwt的过期时间,这个过期时间必须要大于签发时间

nbf: 定义在什么时间之前,该jwt都是不可用的

iat: jwt的签发时间

jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

{"sub": "1234567890","name": "John Doe","iat": 1516239022
}

对应base64UrlEncode编码为:

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ

说明:该字段为json格式,表明用户身份的数据,可以自己自定义字段,很灵活。sub 面向的用户,name 姓名 ,iat 签发时间。例如可自定义示例如下:

{"iss": "admin",     //该JWT的签发者"iat": 1535967430,    //签发时间"exp": 1535974630,    //过期时间"nbf": 1535967430,     //该时间之前不接收处理该Token"sub": "www.admin.com",  //面向的用户"jti": "9f10e796726e332cec401c569969e13e"  //该Token唯一标识
}

signature部分:

jwt的第三部分是一个签证信息,这个签证信息由三部分组成:

  • header (base64后的)
  • payload (base64后的)
  • secret
HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),123456
)

对应的签名为:

keH6T3x1z7mmhKL1T3r9sQdAxxdzB6siemGMr_6ZOwU

最终得到的JWT的json为(header.payload.signature):

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.keH6T3x1z7mmhKL1T3r9sQdAxxdzB6siemGMr_6ZOwU

说明:对header和payload进行base64UrlEncode编码后进行拼接。通过key(这里是123456)进行HS256算法签名。

JWT的使用流程

  • 初次登录:用户初次登录,输入用户名密码
  • 密码验证:服务器从数据库取出用户名和密码进行验证
  • 生成JWT:服务器端验证通过,根据从数据库返回的信息,以及预设规则,生成JWT
  • 返还JWT:服务器的HTTP RESPONSE中将JWT返还
  • 带JWT的请求:以后客户端发起请求,HTTP REQUEST
  • HEADER中的Authorizatio字段都要有值,为JWT
  • 服务器验证JWT

PHP如何实现JWT

这里使用的是PHP 7.0.31,我们新建一个文件jwtAuth.php,完整类代码如下:

<?php
/*** PHP实现jwt*/
class JwtAuth {//头部private static $header=array('alg'=>'HS256', //生成signature的算法'typ'=>'JWT'  //类型);//使用HMAC生成信息摘要时所使用的密钥private static $key='root123456';/*** 获取jwt token* @param array $payload jwt载荷  格式如下非必须* [* 'iss'=>'jwt_admin', //该JWT的签发者* 'iat'=>time(), //签发时间* 'exp'=>time()+7200, //过期时间* 'nbf'=>time()+60, //该时间之前不接收处理该Token* 'sub'=>'www.mano100.cn', //面向的用户* 'jti'=>md5(uniqid('JWT').time()) //该Token唯一标识* ]* @return bool|string*/public static function getToken(array $payload){if(is_array($payload)){$base64header=self::base64UrlEncode(json_encode(self::$header,JSON_UNESCAPED_UNICODE));$base64payload=self::base64UrlEncode(json_encode($payload,JSON_UNESCAPED_UNICODE));$token=$base64header.'.'.$base64payload.'.'.self::signature($base64header.'.'.$base64payload,self::$key,self::$header['alg']);return $token;}else{return false;}}/*** 验证token是否有效,默认验证exp,nbf,iat时间* @param string $Token 需要验证的token* @return bool|string*/public static function verifyToken(string $Token){$tokens = explode('.', $Token);if (count($tokens) != 3)return false;list($base64header, $base64payload, $sign) = $tokens;//获取jwt算法$base64decodeheader = json_decode(self::base64UrlDecode($base64header), JSON_OBJECT_AS_ARRAY);if (empty($base64decodeheader['alg']))return false;//签名验证if (self::signature($base64header . '.' . $base64payload, self::$key, $base64decodeheader['alg']) !== $sign)return false;$payload = json_decode(self::base64UrlDecode($base64payload), JSON_OBJECT_AS_ARRAY);//签发时间大于当前服务器时间验证失败if (isset($payload['iat']) && $payload['iat'] > time())return false;//过期时间小宇当前服务器时间验证失败if (isset($payload['exp']) && $payload['exp'] < time())return false;//该nbf时间之前不接收处理该Tokenif (isset($payload['nbf']) && $payload['nbf'] > time())return false;return $payload;}/*** base64UrlEncode  https://jwt.io/ 中base64UrlEncode编码实现* @param string $input 需要编码的字符串* @return string*/private static function base64UrlEncode(string $input){return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));}/*** base64UrlEncode https://jwt.io/ 中base64UrlEncode解码实现* @param string $input 需要解码的字符串* @return bool|string*/private static function base64UrlDecode(string $input){$remainder = strlen($input) % 4;if ($remainder) {$addlen = 4 - $remainder;$input .= str_repeat('=', $addlen);}return base64_decode(strtr($input, '-_', '+/'));}/*** HMACSHA256签名  https://jwt.io/ 中HMACSHA256签名实现* @param string $input 为base64UrlEncode(header).".".base64UrlEncode(payload)* @param string $key* @param string $alg  算法方式* @return mixed*/private static function signature(string $input, string $key, string $alg = 'HS256'){$alg_config=array('HS256'=>'sha256');return self::base64UrlEncode(hash_hmac($alg_config[$alg], $input, $key,true));}
}

这里测试一下

//测试和官网是否匹配begin$payload=array('sub'=>'1234567890','name'=>'John Doe','iat'=>1516239022);$jwt=new Jwt;$token=$jwt->getToken($payload);echo "<pre>";echo $token;//对token进行验证签名$getPayload=$jwt->verifyToken($token);echo "<br><br>";var_dump($getPayload);echo "<br><br>";//测试和官网是否匹配end//自己使用测试begin$payload_test=array('iss'=>'admin','iat'=>time(),'exp'=>time()+7200,'nbf'=>time(),'sub'=>'www.admin.com','jti'=>md5(uniqid('JWT').time()));;$token_test=Jwt::getToken($payload_test);echo "<pre>";echo $token_test;//对token进行验证签名$getPayload_test=Jwt::verifyToken($token_test);echo "<br><br>";var_dump($getPayload_test);echo "<br><br>";//自己使用时候end

以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要

PHP进阶架构师>>>视频、面试文档免费获取​docs.qq.com

或者关注咱们下面的专栏

PHP架构师之路​zhuanlan.zhihu.com

来源:https://zhuanlan.zhihu.com/p/93910087

php 模数 指数 公钥生成_php实现JWT认证相关推荐

  1. 生成rs256格式jwt

    生成rs256格式jwt //证书文件 String key_location = "config/tls/keystore.p12"; //密钥库密码 String keysto ...

  2. java dsa 私钥_OpenSSL工具 DSA私钥及公钥生成

    DSA私钥及公钥生成 两种生成方式,任选其一即可: 1.使用蚂蚁开放平台提供的工具生成: Windows, MAC OSX. 解压打开文件夹,直接运行"DSA生成公钥私钥转换PCKS8.ba ...

  3. BTC公钥生成地址的过程详解

    BTC公钥生成地址的过程详解 首先简单介绍一下,BTC助记词以及种子和公私钥之间的关系:BTC助记词生成种子,种子生成私钥,私钥生成公钥,公钥生成地址. 本文主要的内容是介绍公钥生成地址的这一过程: ...

  4. Java Token登录验证 使用jjwt生成和解析JWT

    Java jjwt生成和解析Token 参考 依赖 流程 生成和解析Jwt 生成jwt 解析Jwt 实例 后端 前端 刚学会了点使用Jwt来验证登录,记录下来 参考 JSON Web Tokens官网 ...

  5. Spring Security 实战:使用 JWT 认证访问接口

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 1. 前言 欢迎阅读Spring Security 实战 ...

  6. 如何简单的在 ASP.NET Core 中集成 JWT 认证?

    前情提要:ASP.NET Core 使用 JWT 搭建分布式无状态身份验证系统 文章超长预警(1万字以上),不想看全部实现过程的同学可以直接跳转到末尾查看成果或者一键安装相关的 nuget 包 自上一 ...

  7. JWT认证原理、整合springboot实战应用

    JWT认证原理.整合springboot实战应用 1.什么是JWT 2.JWT能做什么 3.与传统的session认证做对比 4.JWT结构 5.JWT的封装方法 1.什么是JWT JWT(Json ...

  8. DRF访问控制(RBAC)、JWT认证

    目录 RBAC 什么是RBAC Django的内置RBAC(六表) 表关系 实操 登录admin操作 admin二次开发 base64编码与解码 JWT认证 为什么使用JWT 认证? Session机 ...

  9. jwt 私钥_一分钟带你了解JWT认证

    一.JWT简介 JSON Web Token(JWT)是一个开放的标准(RFC 7519),它定义了一个紧凑且自包含的方式,用于在各方之间作为JSON对象安全地传输信息.由于此信息是经过数字签名的,因 ...

最新文章

  1. JMS - QueueBrowser
  2. NumPy之:数据类型
  3. Spring框架中的单例Bean是线程安全的吗
  4. os.path vs pathlib
  5. python基础分析_python基础--函数全解析(1)
  6. 如何在单例模式下禁止init
  7. python拆分合并文件_python实现文件的分割与合并
  8. LBP(Local Binary Patterns)局部二进制模式
  9. C++的类型强制转换,static_cast,dynamic_cast,const_cast,reinterpret_cast
  10. 用puttygen工具把私钥id_rsa转换成公钥id_rsa.ppk
  11. img里的align属性能保证图文的混排效果以及vspace和hspace
  12. 你根本就不会使用Notes!
  13. 【转】金蝶EAS BOS工作流开发(附带JAVA脚本)
  14. 那些一秒搞定微软公司Excel的神操作(上)!
  15. Java开发常用软件列表——持续更新
  16. php yii应用运维,Yii 框架应用(Applications)操作实例详解
  17. 2_嵌入式软件开发简介
  18. SD卡的驱动(linux操作系统下)
  19. 用jQuery添加dragstart,dragover和drop事件,实现拖拽效果
  20. python抓取直播源 并更新_Python爬虫实例(二)使用selenium抓取斗鱼直播平台数据...

热门文章

  1. sdut 双向队列(STL)
  2. Fluid给数据弹性一双隐形的翅膀 (1) -- 自定义弹性伸缩
  3. 淘宝直播在智能互动领域的探索及落地
  4. 科学地花钱:基于端智能的在线红包分配方案
  5. 上学帮:阿里云助力教育资讯平台防爬虫
  6. 【远程沟通】“云答辩”“云招聘”双管齐下,解救“最难毕业生”
  7. 如何查看使用 Cloud Toolkit 部署应用的实时日志
  8. 58 集团大规模 Storm 任务平滑迁移至 Flink 的秘密
  9. 如何在Flutter上优雅地序列化一个对象
  10. 性能诊断利器 JProfiler 快速入门和最佳实践