PHP JWT初识及其简单示例

一直没有好好看过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

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

(0)

相关推荐

  • php JWT在web端中的使用方法教程

    解释一下JWT JWT就是一个字符串,经过加密处理与校验处理的字符串,由三个部分组成.基于token的身份验证可以替代传统的cookie+session身份验证方法.三个部分分别如下: header.payload.signature header部分组成 header 格式为: { "typ":"JWT", "alg":"HS256" } 这就是一个json串,两个字段都是必须的,alg字段指定了生成signature的算法

  • php 后端实现JWT认证方法示例

    JWT是什么 JWT是json web token缩写.它将用户信息加密到token里,服务器不保存任何用户信息.服务器通过使用保存的密钥验证token的正确性,只要正确即通过验证.基于token的身份验证可以替代传统的cookie+session身份验证方法. 它定义了一种用于简洁,自包含的用于通信双方之间以 JSON 对象的形式安全传递信息的方法.JWT 可以使用 HMAC 算法或者是 RSA 的公钥密钥对进行签名.它具备两个特点: 简洁(Compact):可以通过URL, POST 参数或

  • PHP JWT初识及其简单示例

    一直没有好好看过jwt,直到前两天要做web验证,朋友给我推荐了jwt.才发现jwt已经被大家广泛的应用了.看来我有点out了.哈哈,趁着这个世界来好好看看这个. JWT(JSON Web Token), 顾名思义就是可以在Web上传输的token,这种token是用JSON格式进行format的.它是一个开源标准(RFC 7519),定义了一个紧凑的自包含的方式在不同实体之间安全的用JSON格式传输信息. 由于现在很多项目都是前后端分离,restful api模式.所以传统的session模式

  • 详解Node.js使用token进行认证的简单示例

    本文只介绍简单的应用,关于json web token的具体介绍以及原理请参考阮一峰老师的JSON Web Token 入门教程. 使用的Node框架是koa2,前端发送ajax请求使用axios 首先创建工程目录: static中存放静态资源,views存放前端模板,server.js为后端代码. 安装必要的依赖项: "dependencies": { "@koa/router": "^8.0.8", "jsonwebtoken&qu

  • java求100之内的素数(质数)简单示例

    质数又称素数.一个大于1的自然数,如果除了1和它自身外,不能被其他自然数整除的数:否则称为合数.根据算术基本定理,每一个比1大的整数,要么本身是一个质数,要么可以写成一系列质数的乘积:而且如果不考虑这些质数在乘积中的顺序,那么写出来的形式是唯一的.下面是一个java求100之内的素数简单示例 复制代码 代码如下: public class test { public static void main(String[] args) {  int i,n,k=0;     for (n = 3; n

  • CI框架入门之MVC简单示例

    本文实例讲述了CI框架入门之MVC简单示例.分享给大家供大家参考,具体如下: 最简单的CI模型: 注意:模型需要用到数据库 配置文件在appcation/config.php 这里我们要用到数据库,需要将databases.php中的相关参数填写一下,具体不再赘述. 直接进入主题: MVC: 1.首先谈"M" 模型 CI中的模型存放在application/models文件夹里 命名规则是:类名_model.php 文件中只包含一个类: 如: class Nb_model extend

  • jquery easyui DataGrid简单示例

    一.简单示例 HTML <table id="tbList" striped="true" rownumbers="true" fix="true" fitcolumns="true" title="标题" idfield="ID" checkbox="true" url="@Url.Action("ListData&qu

  • Vue.js展示AJAX数据简单示例讲解

    最近琢磨了一下vue.js,并在项目中进行了运用,感觉非常好用,强烈推荐. 当通过AJAX方式取回数据后,使用vue.js可以完美地按一定逻辑在页面上的展示数据,代码简单.优美.自然,而且便于与在用的页面框架集成. 感谢vue.js的作者,官方网站地址:https://cn.vuejs.org 举个小例子.注意,代码中使用jQuery.bootstrap.没有用过bootstrap不影响阅读本文. 一.返回的JSON数据示例 [ {"playid":"12113c676a4e

  • C++实现调用系统时间简单示例

    本文简述了基于VC++实现的调用系统时间的简单示例,这里只列出主要部分代码,供大家参考一下,具体如下: 首先要注意添加头文件: #include <Windows.h> 然后就简单了,这里只粘出主要用法如下: #ifdef _SECURITY SYSTEMTIME sysTime; ZeroMemory(&sysTime, sizeof(sysTime)); GetLocalTime(&sysTime); if (sysTime.wYear > _DURE_DATE_YE

  • Java 基础 byte[]与各种数据类型互相转换的简单示例

    Java 基础 byte[]与各种数据类型互相转换的简单示例 这里对byte[]类型对long,int,double,float,short,cahr,object,string类型相互转换的实例, 在socket开发过程中,通常需要将一些具体的值(这些值可能是各种Java类型)转化为byte[]类型,为此我总结了如下这个示例,贴出来,以便经常翻看: public class TestCase { /** * short到字节数组的转换. */ public static byte[] shor

  • C#判断数据类型的简单示例代码

    C#判断数据类型的简单示例代码: 复制代码 代码如下: int   i   =   5; Console.WriteLine( "i is an int? {0}",i.GetType()==typeof(int)); Console.WriteLine( "i is an int? {0}",typeof(int).IsInstanceOfType(i));

  • 浅谈Android单元测试的作用以及简单示例

    前提概要 受人嫌弃的单元测试 对于单元测试这个知识点,其实很多开发者是不太接触的,包括笔者,在实习之前也并未实用过单元测试,或者说并没感受到单元测试的好处. 对于bug的调试,笔者之前更倾向于使用log和断点调试,可以说会了这两个,大部分的逻辑bug都能自己解决了.这两个与看似臃肿的单元测试代码相比更受大家的喜爱. 但是,使用log和断点调试的前提是开发人员较少,甚至是单人开发的情况.如果我自己开发,我完全可以每次都使用集成测试,我知道每一个功能会涉及哪些模块的代码,然后根据逻辑设置log或者断

随机推荐