JWT(JSON Web Token)的基本认识

JWT的基本认识

  • 什么是JWT(JSONWeb令牌)
  • JSONWeb令牌结构
    • 标头
    • 有效载荷
    • 签名
    • 三部分拼凑在一起
    • 总结
    • 标准视图
  • jwt的简易流程
  • 如何在django中使用JWT
    • 在settings.py配置相关数据
    • 下面是具体实现
      • 在serializers.py文件中创建下面内容
        • 创建令牌发送给前端
      • 将token返回给前端

什么是JWT(JSONWeb令牌)

JWT(JSON Web Token) 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

JSONWeb令牌结构

JSONWeb令牌以其紧凑的形式由点分隔的三个部分组成(.),它们是:
第一部分我们称它为头部(header),

第二部分我们称其为载荷(payload, 类似于飞机上承载的物品),

第三部分是签证(signature).
因此,JWT通常如下所示。

xxxxx.yyyyy.zzzzz

让我们分出不同的部分。

标头

标头典型由两个部分组成:令牌的类型(即JWT)和正在使用的签名算法(如HMAC SHA 256或RSA)。
声明类型,这里是jwt
声明加密的算法 通常直接使用 HMAC SHA256

例如:

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

那么,这个JSON是Base64Url编码成JWT的第一部分。

有效载荷

令牌的第二部分是有效负载,它包含索赔。声明是关于实体(通常是用户)和其他数据的语句。有三种类型的索赔:
1.标准中注册的声明
2.公共的声明:使用JWT的用户可以随意定义这些内容。但是为了避免碰撞,应该在IANA JSON Web令牌注册表或者被定义为包含抗冲突命名空间的URI。
3.私有的声明:这些是定制的索赔,目的是在同意使用这些信息的各方之间共享信息,但两者都不是。注册或公众索赔。
例如,有效载荷可以是:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

然后,有效载荷将被Base64Url编码成JSONWeb令牌的第二部分。

请注意,对于签名的令牌,这些信息虽然受到保护,但任何人都可以阅读。除非加密,否则不要将秘密信息放入JWT的有效负载或头元素中。

签名

要创建签名部分,您必须接受编码的头部、编码的有效载荷、秘密、标头中指定的算法,并对其进行签名。

例如,如果要使用HMAC SHA 256算法,则将以下列方式创建签名:

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

签名用于验证消息在过程中没有被更改,对于用私钥签名的令牌,它还可以验证JWT的发送方是否是它所称的发送方。

注意:secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。

三部分拼凑在一起

相当于jwt = [1+2+(1+2+3)]
1=base64加密
2=base64加密
(1+2+3)=alg加密
jwt = HMAC SHA 256加密

输出是三个Base64-URL字符串,由点分隔,可以在HTML和HTTP环境中轻松地传递,同时与基于XML的标准(如SAML)相比更加紧凑。

下面显示了一个JWT,该JWT对前面的头和有效负载进行了编码,并使用一个秘密对其进行了签名。
JWT(JSON Web Token)的基本认识_第1张图片

总结

优点

因为json的通用性,所以JWT是可以进行跨语言支持的,像JAVA,JavaScript,NodeJS,PHP等很多语言都可以使用。
因为有了payload部分,所以JWT可以在自身存储一些其他业务逻辑所必要的非敏感信息。
便于传输,jwt的构成非常简单,字节占用很小,所以它是非常便于传输的。
它不需要在服务端保存会话信息, 所以它易于应用的扩展
安全相关
不应该在jwt的payload部分存放敏感信息,因为该部分是客户端可解密的部分。
保护好secret私钥,该私钥非常重要。

如果您想使用jwt并将这些概念付诸实践,您可以使用jwt.io调试器若要解码、验证和生成JWT,请执行以下操作。
https://jwt.io/#debugger-io

标准视图

JWT(JSON Web Token)的基本认识_第2张图片

jwt的简易流程

JWT(JSON Web Token)的基本认识_第3张图片

如何在django中使用JWT

推荐查看官网进行配置:https://github.com/GetBlimp/django-rest-framework-jwt/blob/master/docs/index.md

在settings.py配置相关数据

import datatime
REST_FRAMEWORK = {
    # 异常处理指定
    'EXCEPTION_HANDLER': 'shanghuishop.utils.exceptions.code_exp_handler',
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',  # session认证
        'rest_framework.authentication.BasicAuthentication'  # 基本认证
    )
}
# 设置过期时间
JWT_AUTH = {
    'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=60*60*24),
}

在序列化中声明

 token = serializers.CharField(label='令牌JWT-TOKEN',read_only=True)
    #创建序列化器
    class Meta:
        model = models.User
        fields = ('id','username','email','password','phone','cpas','msg_code','checkbox','token',)

下面是具体实现

在serializers.py文件中创建下面内容

创建令牌发送给前端

#JWT加密 手动创建新令牌
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        print('payload',payload)
        token = jwt_encode_handler(payload)
        print('token',token)

        #todo 将令牌传递给前端,给对象动态增加属性方式
        user.token = token

        return user

将token返回给前端

success:function (data) {
                alert(data)
                console.log(data);
                //清空token
                localStorage.clear();
                //储存token
                localStorage.token=data['token'];
                //返回到前端

                console.log( '返回到前端')
                console.log( localStorage.token)

            },

你可能感兴趣的:(框架)