JWT能够很好的应用在restful api模式上

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

如今,许多项目模式基本都是前端分离和restful api模式。  所以,传统的session模式没法知足认证要求,这时就出现了jwt。  能够说,restful api模式对于jwt是一个很好的应用场景。

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设置惟一标示

接下来咱们来看一个例子php

<?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 = FirebaseJWTJWT::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) FirebaseJWTJWT::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;
}

这个例子里面用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的一些经常使用配置git

$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的使用大概就是这些。上面的代码在你使用的时候可能会出现两个问题:
一、命名空间错误
解决:不使用命名空间的话,使用require引入文件。若是使用命名空间出现错误,请检查命名空间的路径。

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

相关文章
相关标签/搜索