深入浅出: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了。

参数解释


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

第二部分 JWT使用流程

1.png

实现步骤:

  • 用户登录:输入用户名和密码
  • 服务器进行用户名和密码的校验,通过之后生成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的天涯路,转载请注明出处。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容