新知一下
海量新知
6 0 8 8 8 0 3

[精选] JWT是什么?怎么用?你会用?

php自学中心 | 用编程思想感受你的生活 2021/12/02 14:24

什么是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

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的一些常用配置

$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


更多“JWT”相关内容

更多“JWT”相关内容

新知精选

更多新知精选