一直没有好好看过jwt,直到前两天要做web验证,朋友给我推荐了jwt。才发现jwt已经被大家广泛的应用了。看来我有点out了。哈哈,趁着这个世界来好好看看这个。

JWT(JSON Web Token), 顾名思义就是可以在Web上传输的token,这种token是用JSON格式进行format的。它是一个开源标准(RFC 7519),定义了一个紧凑的自包含的方式在不同实体之间安全的用JSON格式传输信息。

由于现在很多项目都是前后端分离,restful api模式。所以传统的session模式就没有办法满足认证需求,这个时候jwt的作用就来了。可以说 restful api认证是jwt的一个很好的应用场景。

下面是一个很小的demo


<?php
require_once 'src/JWT.php';
header('Content-type:application/json');
//定义Key
const KEY = 'dasjdkashdwqe1213dsfsn;p'; $user = [
'uid'=>'dadsa-12312-vsd1s1-fsds',
'account'=>'daisc',
'password'=>'123456'
];
$redis = redis();
$action = $_GET['action'];
switch ($action)
{
case 'login':
login();
break;
case 'info':
info();
break; }
//登陆,写入验证token
function login()
{
global $user;
$account = $_GET['account'];
$pwd = $_GET['password'];
$res = [];
if($account==$user['account']&&$pwd==$user['password'])
{
unset($user['password']);
$time = time();
$token = [
'iss'=>'http://test.cc',//签发者
'iat'=>$time,
'exp'=>$time+60,
'data'=>$user
];
$jwt = \Firebase\JWT\JWT::encode($token,KEY);
$res['code'] = 200;
$res['message'] = '登录成功';
$res['jwt'] = $jwt; }
else
{
$res['message']= '用户名或密码错误';
$res['code'] = 401;
}
exit(json_encode($res));
} function info()
{
$jwt = $_SERVER['HTTP_AUTHORIZATION'] ?? false;
$res['code'] = 200;
if($jwt)
{
$jwt = str_replace('Bearer ','',$jwt);
if(empty($jwt))
{
$res['code'] = 401;
$res['msg'] = 'You do not have permission to access.';
exit(json_encode($res));
}
try{
$token = (array) \Firebase\JWT\JWT::decode($jwt,KEY, ['HS256']);
if($token['exp']<time())
{
$res['code'] = 401;
$res['msg'] = '登录超时,请重新登录';
}
$res['data']= $token['data'];
}catch (\Exception $E)
{
$res['code'] = 401;
$res['msg'] = '登录超时,请重新登录.';
}
}
else
{
$res['code'] = 401;
$res['msg'] = 'You do not have permission to access.';
}
exit(json_encode($res));
} //连接redis
function redis()
{
$redis = new Redis();
$redis->connect('127.0.0.1');
return $redis;
}

这个dmeo里面用jwt做了一个简单的认证。 其中用到了一个php-jwt的加密包https://github.com/firebase/php-jwt

其中KEY为定义的私钥也就是jwt里面的 sign部分,这个一定要保存好。
header部分php-jwt包里面已经帮我们完成了,加密代码如下


*/
public static function encode($payload, $key, $alg = 'HS256', $keyId = null, $head = null)
{
$header = array('typ' => 'JWT', 'alg' => $alg);
if ($keyId !== null) {
$header['kid'] = $keyId;
}
if ( isset($head) && is_array($head) ) {
$header = array_merge($head, $header);
}
$segments = array();
$segments[] = static::urlsafeB64Encode(static::jsonEncode($header));
$segments[] = static::urlsafeB64Encode(static::jsonEncode($payload));
$signing_input = implode('.', $segments); $signature = static::sign($signing_input, $key, $alg);
$segments[] = static::urlsafeB64Encode($signature); return implode('.', $segments);
}

可以看出默认的加密的方式是HS256。这也是说jwt安全的原因。现阶段HS256加密还是很安全的。
这个包里面也支持证书加密。

加密解密的过程这个包已经帮我们完成了。所以我们只需要定义jwt中的 poyload部分就可以了。也就是demo里面的token部分。加密成功会得到一个加密的Jwt字符串,下次前端在请求api的时候需要携带这个jwt字符串作为认证。
在header头里面增加Authorization。在服务端验证的时候回通过取得这个值来验证回话的有效。

下面是poyload的一些常用配置


$token = [
#非必须。issuer 请求实体,可以是发起请求的用户的信息,也可是jwt的签发者。
"iss" => "http://example.org",
#非必须。issued at。 token创建时间,unix时间戳格式
"iat" => $_SERVER['REQUEST_TIME'],
#非必须。expire 指定token的生命周期。unix时间戳格式
"exp" => $_SERVER['REQUEST_TIME'] + 7200,
#非必须。接收该JWT的一方。
"aud" => "http://example.com",
#非必须。该JWT所面向的用户
"sub" => "jrocket@example.com",
# 非必须。not before。如果当前时间在nbf里的时间之前,则Token不被接受;一般都会留一些余地,比如几分钟。
"nbf" => 1357000000,
# 非必须。JWT ID。针对当前token的唯一标识
"jti" => '222we',
# 自定义字段
"GivenName" => "Jonny",
# 自定义字段
"name" => "Rocket",
# 自定义字段
"Email" => "jrocket@example.com", ];

里面包含的配置可以自由配置,也可以自己添加一些其他的。这些都是网上大家常用的,可以说是一种约定吧。

对于jwt还有很多有疑问的地方,下来在慢慢研究,比如续期以及退出的问题

原文地址:https://segmentfault.com/a/1190000016633900

PHP JWT初识的更多相关文章

  1. JWT初识记录

    因为前一段时间做了一个系统持续操作期间自动刷新token有效性的需求,然后就想着找一个空闲时间总结一下JWT,所以今天就简单的记录一下自己了解的内容. JWT是什么 JWT全称是JSON Web To ...

  2. 初识SSO与JWT

    以前在学校做项目的时候,登录注销,权限验证这些事情,都是交给框架来做的,每次都是把这个架子拿到项目中去,也没有真正思考过它的过程,总觉的这些都是十分简单的逻辑. 然而来公司工作之后,慢慢觉得登录和权限 ...

  3. Spring Boot初识(4)- Spring Boot整合JWT

    一.本文介绍 上篇文章讲到Spring Boot整合Swagger的时候其实我就在思考关于接口安全的问题了,在这篇文章了我整合了JWT用来保证接口的安全性.我会先简单介绍一下JWT然后在上篇文章的基础 ...

  4. 初识单点登录及JWT实现

    单点登录 多系统,单一位置登录,实现多系统同时登录的一种技术 (三方登录:某系统使用其他系统的用户,实现本系统登录的方式.如微信登录.支付宝登录) 单点登录一般是用于互相授信的系统,实现单一位置登录, ...

  5. 初识JWT

    1.JWT是什么 官方网站 JWT是JSON Web Token的简称.是一种开放标准(RFC 7519),定义了一种紧凑且自包含的方式,以JSON对象的形式在各方之间安全地传输信息,因为他被数字签名 ...

  6. ASP.NET Core WebAPI中使用JWT Bearer认证和授权

    目录 为什么是 JWT Bearer 什么是 JWT JWT 的优缺点 在 WebAPI 中使用 JWT 认证 刷新 Token 使用授权 简单授权 基于固定角色的授权 基于策略的授权 自定义策略授权 ...

  7. drf框架 - JWT认证插件

    JWT认证 JWT认证方式与其他认证方式对比: 优点 1) 服务器不要存储token,token交给每一个客户端自己存储,服务器压力小 2)服务器存储的是 签发和校验token 两段算法,签发认证的效 ...

  8. ASP.NET Web API 2系列(四):基于JWT的token身份认证方案

    1.引言 通过前边的系列教程,我们可以掌握WebAPI的初步运用,但是此时的API接口任何人都可以访问,这显然不是我们想要的,这时就需要控制对它的访问,也就是WebAPI的权限验证.验证方式非常多,本 ...

  9. CAS单点登录(一)——初识SSO

    转载:https://blog.csdn.net/Anumbrella/article/details/80821486 一.初识CAS 首先我们来说一下CAS,CAS全称为Central Authe ...

随机推荐

  1. shell脚本切割tomcat日志文件

    转自:http://www.cnblogs.com/lishun1005/p/6054816.html 鉴于在调试logback和log4j的文件切割一直无法成功,随性用shell写个脚本用来切割to ...

  2. 《Exception》第八次团队作业:Alpha冲刺(大结局)

    一.项目基本介绍 项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 作业链接地址 团队名称 Exception 作业学习目标 1.掌握软件测试基础技术.2.学习迭代式增量软 ...

  3. Vijos 1456 最小总代价 (状压dp)

    看到这道题n只有16,就可以想到状压dp 每个人只有经过或者没经过,那就用1表示经过,0表示没经过 但是不是当前在谁那里,所以再加一维来记录 所以f[state][i]表示在物品在i,当前的状态是st ...

  4. JAVA 多线程知识总结(一)

    一,线程的生命周期以及五种基本状态 关于JAVA线程的生命周期,首先看一下下面这张图 上图中基本上囊括了Java中多线程各重要知识点.掌握了上图中的各知识点,Java中的多线程也就基本上掌握了. Ja ...

  5. 华硕 X201E 拆机

    每次笔记本拆机,装好之后.就会发现多了几个螺丝,忘了从哪拧下来了 以下记录下华硕 X201E 清灰拆机过程 1:电脑正面图 2:背面图,一共9个螺丝 3:背面的9个螺丝拧下来,把后盖沿着缝隙扣下来 w ...

  6. OC 自己定义 setDateFormat 显示格式

    -(NSString *)getStringFromDate:(NSDate *)aDate { NSDateFormatter *dateFormater=[[NSDateFormatter all ...

  7. bzoj4519: [Cqoi2016]不同的最小割(分治最小割)

    4519: [Cqoi2016]不同的最小割 题目:传送门 题解: 同BZOJ 2229 基本一样的题目啊,就最后用set记录一下就ok 代码: #include<cstdio> #inc ...

  8. nyoj--37--回文字符串(动态规划)

    回文字符串 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 所谓回文字符串,就是一个字符串,从左到右读和从右到左读是完全一样的,比如"aba".当然, ...

  9. BZOJ 3160 FFT+Manacher

    思路: 这道题思路好奇怪--. 我们先要知道关于x (x可以是间隙) 对称的有几对字母 显然暴力是n^2的 那怎么办呢 先把所有'a'看成1 'b'看成0 意外的发现 这不就是卷积嘛 再倒过来搞一搞 ...

  10. VC6.0 设置动态链接库工程生成dll以及lib文件的位置

    在"Projet"->"Settings..."的"Link"选项卡中 "Output file name"中设置 ...