JSON Web Tokens,是一种开发的行业标准 RFC 7519 ,用于安全的表示双方之间的声明。目前,jwt广泛应用在系统的用户认证方面,特别是现在前后端分离项目。

1. jwt认证流程

在项目开发中,一般会按照上图所示的过程进行认证,即:用户登录成功之后,服务端给用户浏览器返回一个token,以后用户浏览器要携带token再去向服务端发送请求,服务端校验token的合法性,合法则给用户看数据,否则,返回一些错误信息。

传统token方式和jwt在认证方面有什么差异?

  • 传统token方式

    用户登录成功后,服务端生成一个随机token给用户,并且在服务端(数据库或缓存)中保存一份token,以后用户再来访问时需携带token,服务端接收到token之后,去数据库或缓存中进行校验token的是否超时、是否合法。
  • jwt方式

    用户登录成功后,服务端通过jwt生成一个随机token给用户(服务端无需保留token),以后用户再来访问时需携带token,服务端接收到token之后,通过jwt对token进行校验是否超时、是否合法。

2. jwt创建token

2.1 原理

jwt的生成token格式如下,即:由 . 连接的三段字符串组成。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

生成规则如下:

  • 第一段HEADER部分,固定包含算法和token类型,对此json进行base64url加密,这就是token的第一段。

    {
    "alg": "HS256",
    "typ": "JWT"
    }
  • 第二段PAYLOAD部分,包含一些数据,对此json进行base64url加密,这就是token的第二段
    {
    "sub": "1234567890",
    "name": "John Doe",
    "iat": 1516239022
    ...
    }
  • 第三段SIGNATURE部分,把前两段的base密文通过.拼接起来,然后对其进行HS256加密,再然后对hs256密文进行base64url加密,最终得到token的第三段。
    base64url(
    HMACSHA256(
    base64UrlEncode(header) + "." + base64UrlEncode(payload),
    your-256-bit-secret (秘钥加盐)
    )
    )

最后将三段字符串通过 .拼接起来就生成了jwt的token。

注意:base64url加密是先做base64加密,然后再将 - 替代 +_ 替代 /

2.2 代码实现

基于Python的pyjwt模块创建jwt的token。

  • 安装

    pip3 install pyjwt
  • 实现 
    import jwt
    import datetime
    from jwt import exceptions SALT = 'iv%x6xo7l7_u9bf_u!9#g#m*)*=ej@bek5)(@u3kh*72+unjv=' def create_token(): # 构造header
    headers = {
    'typ': 'jwt',
    'alg': 'HS256'
    }
    # 构造payload
    payload = {
    'user_id': 1, # 自定义用户ID
    'username': 'wupeiqi', # 自定义用户名
    'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=5) # 超时时间
    } result = jwt.encode(payload=payload, key=SALT, algorithm="HS256", headers=headers).decode('utf-8')
    return result if __name__ == '__main__':
    token = create_token()
    print(token)

3. jwt校验token

一般在认证成功后,把jwt生成的token返回给用户,以后用户再次访问时候需要携带token,此时jwt需要对token进行超时合法性校验。

获取token之后,会按照以下步骤进行校验:

  • 将token分割成 header_segmentpayload_segmentcrypto_segment 三部分

  • 对第一部分header_segment进行base64url解密,得到header

  • 对第二部分payload_segment进行base64url解密,得到payload

  • 对第三部分crypto_segment进行base64url解密,得到signature

  • 对第三部分signature部分数据进行合法性校验

    • 拼接前两段密文,即:signing_input
    • 从第一段明文中获取加密算法,默认:HS256

    • 使用 算法+盐 对signing_input 进行加密,将得到的结果和signature密文进行比较。

import jwt
import datetime
from jwt import exceptions def get_payload(token):
"""
根据token获取payload
:param token:
:return:
"""
try:
# 从token中获取payload【不校验合法性】
# unverified_payload = jwt.decode(token, None, False)
# print(unverified_payload) # 从token中获取payload【校验合法性】
verified_payload = jwt.decode(token, SALT, True)
return verified_payload
except exceptions.ExpiredSignatureError:
print('token已失效')
except jwt.DecodeError:
print('token认证失败')
except jwt.InvalidTokenError:
print('非法的token') if __name__ == '__main__':
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NzM1NTU1NzksInVzZXJuYW1lIjoid3VwZWlxaSIsInVzZXJfaWQiOjF9.xj-7qSts6Yg5Ui55-aUOHJS4KSaeLq5weXMui2IIEJU"
payload = get_payload(token)

4. jwt实战

4.1 django 案例

在用户登录成功之后,生成token并返回,用户再次来访问时需携带token。

此示例在django的中间件中对tokne进行校验,内部编写了两个中间件来支持用户通过两种方式传递token。

  • url传参

  • Authorization请求头

源码下载:https://pan.baidu.com/s/1ANibEXYocu6V1JfDUydRHw

4.2 django rest framework 案例

在用户登录成功之后,生成token并返回,用户再次来访问时需携带token。

此示例在drf的认证组件中对token进行校验,内部编写了两个认证组件来支持用户通过两种方式传递token。

  • url传参

  • Authorization请求头

源码下载:https://pan.baidu.com/s/14dxnH7YvVNVFwpHEjcBLbg

4.3 flask 案例

在用户登录成功之后,生成token并返回,用户再次来访问时需携带token。

此示例在flask的before_request中对token进行校验,内部编写了两个函数来支持用户通过两种方式传递token。

  • url传参

  • Authorization请求头

源码下载:https://pan.baidu.com/s/13w8on_OBBxAd1Pp4KXETaQ

特别提醒:示例源码地址失效,加交流群或 联系作者 武沛齐(QQ:424662508) 进行获取。

JWT教学视频

jwt揭秘(含源码示例和视频)的更多相关文章

  1. jwt揭秘(含源码示例)

      JSON Web Tokens,是一种开发的行业标准 RFC 7519 ,用于安全的表示双方之间的声明.目前,jwt广泛应用在系统的用户认证方面,特别是现在前后端分离项目. 1. jwt认证流程 ...

  2. 微信公众平台开发-OAuth2.0网页授权(含源码)

    微信公众平台开发-OAuth2.0网页授权接口.网页授权接口详解(含源码)作者: 孟祥磊-<微信公众平台开发实例教程> 在微信开发的高级应用中,几乎都会使用到该接口,因为通过该接口,可以获 ...

  3. C++ JsonCpp 使用(含源码下载)

    C++ JsonCpp 使用(含源码下载) 前言 JSON是一个轻量级的数据定义格式,比起XML易学易用,而扩展功能不比XML差多少,用之进行数据交换是一个很好的选择JSON的全称为:JavaScri ...

  4. 微信公众平台开发-access_token获取及应用(含源码)

    微信公众平台开发-access_token获取及应用(含源码)作者: 孟祥磊-<微信公众平台开发实例教程> 很多系统中都有access_token参数,对于微信公众平台的access_to ...

  5. jQuery使用():Deferred有状态的回调列表(含源码)

    deferred的功能及其使用 deferred的实现原理及模拟源码 一.deferred的功能及其使用 deferred的底层是基于callbacks实现的,建议再熟悉callbacks的内部机制前 ...

  6. ffplay源码分析4-音视频同步

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10307089.html ffplay是FFmpeg工程自带的简单播放器,使用FFmpeg ...

  7. 微信公众平台开发2-access_token获取及应用(含源码)

    微信公众平台开发-access_token获取及应用(含源码) 很多系统中都有access_token参数,对于微信公众平台的access_token参数,微信服务器判断该公众平台所拥有的权限,允许或 ...

  8. 安卓图表引擎AChartEngine(四) - 源码示例 嵌入Acitivity中的折线图

    前面几篇博客中都是调用ChartFactory.get***Intent()方法,本节讲的内容调用ChartFactory.get***View()方法,这个方法调用的结果可以嵌入到任何一个Activ ...

  9. 微信公众平台开发-微信服务器IP接口实例(含源码)

    微信公众平台开发-access_token获取及应用(含源码)作者: 孟祥磊-<微信公众平台开发实例教程> 学习了access_token的获取及应用后,正式的使用access_token ...

随机推荐

  1. WebScraper for Mac(网站数据抓取软件) 4.10.2

    WebScraper Mac版是一款Mac平台上通过使用将数据导出为JSON或CSV的简约应用程序,WebScraper Mac版可以快速提取与某个网页(包括文本内容)相关的信息.WebScraper ...

  2. EXSI的使用

    新建资源池 创建好的资源池和虚拟机 创建用户 角色就是权限的集合 右键点击添加. 创建完角色回到清单资源池 重点新登录 bios有一项叫来电自启动. 添加网桥

  3. LG2145 「JSOI2007」祖码 区间DP

    问题描述 LG2145 题解 把颜色相同的一段看做一个点. 然后类似于合唱队区间DP即可. 但是这题好像出过一些情况,导致我包括题解区所有人需要特判最后一个点. \(\mathrm{Code}\) # ...

  4. Educational Codeforces Round 76 (Rated for Div. 2) A. Two Rival Students 水题

    A. Two Rival Students There are

  5. [学习笔记] Manacher与PAM

    \(1\) Manacher 挺短,背是挺好背的 Manacher用于求回文串长度.思想大概就是: 1.加入字符集之外的识别字符(比如#)分隔开原来相邻的字母,这样所有的回文串都变成了以某个字符为中心 ...

  6. 第04组 Alpha冲刺(3/4)

    队名:斗地组 组长博客:地址 作业博客:Alpha冲刺(3/4) 各组员情况 林涛(组长) 过去两天完成了哪些任务: 1.收集各个组员的进度 2.写博客 展示GitHub当日代码/文档签入记录: 接下 ...

  7. 试着用workerman开发一个在线聊天应用

    聊天功能是很常见的一种功能,Workerman是一款开源高性能异步PHP socket即时通讯框架. 什么是Workerman? Workerman是一款 开源 高性能异步 PHP socket即时通 ...

  8. 世界GDP数据可视化

    各国GDP数据可视化 数据来自世界银行 导入资源包,如下: Pandas, numpy, seaborn 和 matplotlib import pandas as pd import numpy a ...

  9. java核心技术第一篇之数据库基础

    01.数据库的概念: 1).数据库的概念:数据库(Database),就是存储数据的仓库. 2).作用:用来存储和管理大量数据的.内部采用了非常便于查询的机制来存储数据,能保证我们在大量数据的情况下 ...

  10. FCC---Create a More Complex Shape Using CSS and HTML---一个粉色爱心

    One of the most popular shapes in the world is the heart shape, and in this challenge you'll create ...