JWT实现过程及应用

jwt实现过

# 用户登录,返回给客户端token(服务端不保存),用户带着token,服务端拿到token再校验;

1,提交用户名和密码给服务端,如果登陆成功,jwt会创建一个token,并返回;
	第一段:header,内部包含 (算法/token类型)
        {
            "typ": "JWT",    # 声明类型为jwt
            "alg": "HS256"   # 声明签名算法为SHA256
        }
        # json转化字符串做base64url加密,可反解
    第二段:payload,包含(标准中注册的声明、公共声明、私有声明(用户信息))
        {  # 私有声名
            “id”: “12”,
            “name”: “bajie″,
            “exp”: 60        # 超时时间
        }
        # 公共声明:公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.
        """ 注册的声明
            iss: jwt签发者
            sub: jwt所面向的用户
            aud: 接收jwt的一方
            exp: jwt的过期时间,这个过期时间必须要大于签发时间
            nbf: 定义在什么时间之前,该jwt都是不可用的.
            iat: jwt的签发时间
            jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
		"""
        # json转化字符串做base64url加密,可反解
    第三段:
        1,将第一段和第二段的密文拼接
        2,HS256加密 + 加盐
        3,对HS256加密后的密文再用 base64url 加密
2,用户访问,需要携带token,后端进行校验
    1,获取token
    2,切割,对第二段解密,获取payload信息,检测是否超时
    3,把第一段和第二段的密文拼接,再次执行HS256加密 + 加盐   得到  密文
    4,密文 == token 匹配   (如果修改超时时间 则不通过)

  

jwt简单应用

安装: pip install pyjwt
    
import jwt
import datetime
from rest_framework.views import APIView
from rest_framework.response import Response
from jwt import exceptions

from api import models


class LoginAPIview(APIView):
    def get(self, request, *args, **kwargs):
        # 盐
        sail = "sadjmasklfn63a5s62dwa@ddas/352asdfa"
        """
            1,获取token
            2,切割,对第二段解密,获取payload信息,检测是否超时
            3,把第一段和第二段的密文拼接,再次执行HS256加密 + 加盐   得到  密文
            4,密文 == token 匹配   (如果修改超时时间 则不通过)
        """
        token = request.query_params.get("token")
        verified_payload = None
        msg = ''
        try:
            # 反解出来的第二段数据
            verified_payload = jwt.decode(token, sail, True)
        except exceptions.ExpiredSignatureError:  # 超时
            msg = "token失效"
        except jwt.DecodeError:
            msg = "token认证失败"
        except jwt.InvalidTokenError:
            msg = "非法token"

        if not verified_payload:
            return Response({'code': '登录失败', "error": msg})
        # print(verified_payload["id"],verified_payload["username"])
        return Response({"ok": "登陆成功"})

    def post(self, request, *args, **kwargs):
        user = request.data.get('username')
        pswd = request.data.get('password')
        obj = models.UserInfo.objects.filter(username=user, password=pswd).first()
        if obj:
            # 盐
            sail = "sadjmasklfn63a5s62dwa@ddas/352asdfa"
            # 构造 第一段: header, 内部包含(算法 / token类型)  默认
            headers = {
                "typ": "JWT",  # 声明类型为jwt
                "alg": "HS256"  # 声明签名算法为SHA256
            }
            # 第二段: payload, 包含(标准中注册的声明、公共声明、私有声明(用户信息))
            payload = {  # 私有声名
                'id': obj.id,
                'username': obj.username,
                'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=1)  # 超时时间1分钟
            }
            res_token = jwt.encode(headers=headers, payload=payload, key=sail, algorithm='HS256').decode('utf-8')
            return Response({"msg": "登录成功", "token": res_token})

        return Response("0")

  

posted @ 2020-10-31 15:57  bajie_new  阅读(223)  评论(0编辑  收藏  举报