技术人员福音,在家远程部署公司网络,员工都能轻松访问公司内网

本文索引:

  • 第一部分 基本概念
  • 第二部分 使用流程
  • 第三部分 实现代码
深入浅出:JWT(JSON Web Token)鉴权

第一部分 基本概念

JWT就是一个字符串,经过加密处理与校验处理的字符串,由三个部分组成。基于token的身份验证可以替代传统的cookie+session身份验证方法。三个部分分别如下:

 header.payload.signature

header部分:

{
\"typ\":\"JWT\",
\"alg\":\"HS256\"
}

这就是一个json串,两个字段都是必须的,alg字段指定了生成signature的算法,默认值为 HS256,可以自己指定其他的加密算法,如RSA.经过base64encode就可以得到 header.
payload部分:

$payload=[
\'iss\' => $issuer, //签发者
\'iat\' => $_SERVER[\'REQUEST_TIME\'], //什么时候签发的
\'exp\' => $_SERVER[\'REQUEST_TIME\'] + 7200 //过期时间
\'uid\'=>1111
];

signature部分
将 header和 payload使用header中指定的加密算法加密,当然加密过程还需要自定秘钥,自己选一个字符串就可以了。

HMACSHA256(
base64UrlEncode(header) + \".\" +
base64UrlEncode(payload),
secret)

php实现代码:

<?php

public static function encode(array $payload, string $key, string $alg = \'SHA256\')
{
$key = md5($key);
$jwt = self::urlsafeB64Encode(json_encode([\'typ\' => \'JWT\', \'alg\' => $alg])) . \'.\' . self::urlsafeB64Encode(json_encode($payload));
return $jwt . \'.\' . self::signature($jwt, $key, $alg);
}

public static function signature(string $input, string $key, string $alg)
{
return hash_hmac($alg, $input, $key);
}

将以上三个部分连起来就是JWT了。

参数解释

深入浅出:JWT(JSON Web Token)鉴权

Screen-Shot-2018-09-06-at-3.24.30-PM.png

第二部分 JWT使用流程

深入浅出:JWT(JSON Web Token)鉴权

JWT使用流程

实现步骤:

  • 用户登录:输入用户名和密码
  • 服务器进行用户名和密码的校验,通过之后生成JWT返回给前端
  • 每次用户请求API的时候都带上JWT
  • 服务端收到JWT做校验

第三部分 实现代码

首先composer安装一个JWT库,这里使用的是firebase的库,

composer require firebase/php-jwt

服务端在生成token时,加入少量的用户信息,比如用户的id。服务端接收到token之后,可以解析出这些数据,从而将token和用户关联了起来。

使用很简单,传入秘钥,生成Token:

private function generateToken($key){
vendor(\'JWT.JWT\');
$key = $user_key;
$token = array(
\"iss\" => \"https://feifei50.com\", // Issued At Claim
\"aud\" => \"https://feifei50.com\", // Audience Claim
\"iat\" => $_SERVER[\'REQUEST_TIME\'], // Issued At Claim
\"nbf\" => $_SERVER[\'REQUEST_TIME\']-300, // Not Before Claim
\"exp\" => $_SERVER[\"REQUEST_TIME\"]+3600 // Expire Time Claim
);
$jwt = JWT::encode($token, $key);
return $jwt;
}

返回的$jwt大概是这个样子:

//eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvZmVpZmVpNTAuY29tIiwiYXVkIjoiaHR0cHM6XC9cL2ZlaWZlaTUwLmNvbSIsImlhdCI6MTUzNjI2OTM4NSwibmJmIjoxNTM2MjYxMDY1LCJleHAiOjE1MzYyNzk1NjV9.W19LwKH2eQbYs6YHKkbk7bOQK2dBfmV8jcNGIN4OGlY

key就是用来混淆的,自己随便定义好了,encode 需要key,decode 也需要key,这里用md5加密一下,会加入一个令牌混淆加密

在前端拿到这个token之后就将这个token放在LocalStroage中,每发送AJAX请求的时候都带上这个token给服务端,服务端解码这个token来做校验,如果校验没有通过,那么强制其跳回登录页面。

firebase的这个JWT会在解码的时候做部分的校验,比如key是否正确,token是否expired之类的,具体参考源码,很容易理解。以后后端每次拿到这组Token就要从Token中进行解码:

解码Token

private function decodeToken($jwt,$user_key){
JWT::$leeway = 300; // $leeway in seconds
$decoded = JWT::decode($jwt, $user_key, array(\'HS256\'));
return $decoded;
}

这样解码之后就拿到了之前定义的payload的信息即说需要的用户信息。

本文作者熊冰,个人网站[Bing的天涯路],转载请注明出处。

上一篇

现阶段评价最好的几款手机,买它们就对了

下一篇

在娱乐圈的花旦,迪丽热巴是有实力还是炒作爆红呢?

评论已经被关闭。

插入图片
返回顶部