PHP JWT初识及其简单示例


Posted in PHP onOctober 10, 2018

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

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

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

参数解释

名称 解释
iss (issuer) issuer 请求实体,可以是发起请求的用户的信息,也可是jwt的签发者
sub (Subject) 设置主题,类似于发邮件时的主题
aud (audience) 接收jwt的一方
exp (expire) token过期时间
nbf (not before) 当前时间在nbf设定时间之前,该token无法使用
iat (issued at) token创建时间
jti (JWT ID) 对当前token设置唯一标示

下面是一个很小的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的使用大概就是这些。上面的代码在你使用的时候可能会出现两个问题:

1、命名空间错误
解决:不使用命名空间的话,使用require引入文件。如果使用命名空间出现错误,请检查命名空间的路径。

2、生成的token是一个对象
解决:(string)$token 将token强转成string

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
一个更简单的无限级分类菜单代码
Jan 16 PHP
PHP has encountered an Access Violation 错误的解决方法
Jan 17 PHP
php删除文件夹及其文件夹下所有文件的函数代码
Jan 23 PHP
ThinkPHP之M方法实例详解
Jun 20 PHP
微信公众平台开发-微信服务器IP接口实例(含源码)
Mar 05 PHP
PHP实现生成模糊图片的方法示例
Dec 21 PHP
详解laravel安装使用Passport(Api认证)
Jul 27 PHP
PHP call_user_func和call_user_func_array函数的简单理解与应用分析
Nov 25 PHP
PHP框架实现WebSocket在线聊天通讯系统
Nov 21 PHP
Laravel5.1 框架数据库操作DB运行原生SQL的方法分析
Jan 07 PHP
PHP上传图片到数据库并显示的实例代码
Dec 20 PHP
PhpStorm2020 + phpstudyV8 +XDebug的教程详解
Sep 17 PHP
php-fpm.conf配置文件中文说明详解及重要参数说明
Oct 10 #PHP
php实现单笔转账到支付宝功能
Oct 09 #PHP
php实现小程序支付完整版
Oct 09 #PHP
php实现微信企业付款到个人零钱功能
Oct 09 #PHP
php实现构建排除当前元素的乘积数组方法
Oct 06 #PHP
php微信公众号开发之微信企业付款给个人
Oct 04 #PHP
PHP获取当前系统时间的方法小结
Oct 03 #PHP
You might like
PHP XML操作类DOMDocument
2009/12/16 PHP
php生成随机颜色的方法
2014/11/13 PHP
用 javascript 实现的点击复制代码
2007/03/24 Javascript
两个select之间option的互相添加操作(jquery实现)
2009/11/12 Javascript
javascript 打开页面window.location和window.open的区别
2010/03/17 Javascript
jquery.validate使用攻略 第五步 正则验证
2010/07/01 Javascript
uploadify 3.0 详细使用说明
2012/06/18 Javascript
Node.js入门教程:在windows和Linux上安装配置Node.js图文教程
2014/08/14 Javascript
灵活使用数组制作图片切换js实现
2016/07/28 Javascript
bootstrap datetimepicker日期插件使用方法
2017/01/13 Javascript
使用bootstrap-paginator.js 分页来进行ajax 异步分页请求示例
2017/03/09 Javascript
JavaScript累加、迭代、穷举、递归等常用算法实例小结
2018/05/08 Javascript
ES6 如何改变JS内置行为的代理与反射
2019/02/11 Javascript
Layui 导航默认展开和菜单栏选中高亮设置的方法
2019/09/04 Javascript
React Native中ScrollView组件轮播图与ListView渲染列表组件用法实例分析
2020/01/06 Javascript
解决微信小程序scroll-view组件无横向滚动的问题
2020/02/04 Javascript
vue实现表单未编辑或未保存离开弹窗提示功能
2020/04/08 Javascript
[56:42]VP vs RNG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
Python修改Excel数据的实例代码
2013/11/01 Python
跟老齐学Python之??碌某?? target=
2014/09/12 Python
python-docx修改已存在的Word文档的表格的字体格式方法
2018/05/08 Python
python对于requests的封装方法详解
2019/01/03 Python
python虚拟环境迁移方法
2019/01/03 Python
使用Python完成15位18位身份证的互转功能
2019/11/06 Python
Python单链表原理与实现方法详解
2020/02/22 Python
python nohup 实现远程运行不宕机操作
2020/04/16 Python
python实现猜拳游戏项目
2020/11/30 Python
css3中用animation的steps属性制作帧动画
2019/04/25 HTML / CSS
HTML5地理定位_动力节点Java学院整理
2017/07/12 HTML / CSS
Canvas与图片压缩的示例代码
2017/11/28 HTML / CSS
FC-Moto瑞典:欧洲最大的摩托车服装和头盔商店之一
2018/11/27 全球购物
缓解脚、腿和背部疼痛:Z-CoiL鞋
2019/03/12 全球购物
库存图片、照片、矢量图、视频和音乐:Shutterstock
2021/02/12 全球购物
文员自我评价怎么写
2013/09/19 职场文书
美术国培研修感言
2014/02/12 职场文书
小学校长先进事迹材料
2014/05/13 职场文书