Django中的JWT身份验证的实现


Posted in Python onMay 07, 2021

1.认证与授权

1.验证:身份验证是验证个人或设备标识的过程。身份验证过程之一是登录过程。注册网站后,您的信息(ID,密码,名称,电子邮件等)将存储在其数据库中。之后,您无需创建帐户即可提供信息。相反,您只需要提供用户名和密码来验证您的身份,网站就会自动知道您正在访问。

2.授权:授权是用于确定用户特权或访问级别的安全机制。在许多社区网站上,只有上传帖子和管理员的人才能删除它。当其他人尝试删除帖子时,网站应该抛出错误(但是在许多情况下,他们甚至看不到删除按钮)。因此,对于每个请求,用户都需要证明自己具有权限。

2.什么是JWT

JSON Web令牌(JWT)是一种开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间安全地将信息作为JSON对象进行传输。您可以使用JWT对请求进行身份验证和授权。

JWT由三个串联的Base64url编码的字符串(标头,有效负载和签名)组成,并用点号(,)分隔。标头包含有关令牌和加密算法类型的元数据。签名用于验证令牌的可信度。有效负载包含用于身份验证和授权的所有必要数据。

3.存储JWT

当用户登录时,服务器将创建JWT并将其发送到客户端。然后,客户端将其存储到会话存储或本地存储。每次客户端向服务器端发送需要身份验证或授权的请求时,都会在授权标头上发送JWT。易受XSS(跨站点脚本)攻击:会话和本地存储可通过JavaScript访问。恶意第三方可以将其JS注入网站,从而可以向API发出请求。

服务器将JWT存储在Cookie中,并使用存储在Cookie中的JWT验证用户。Cookies容易受到CSRF的攻击,因为它们随每个请求一起发送。因此,恶意的第三方可以轻松地提出意想不到的请求。

4.Django中的JWT

# settings.py
SECRET_KEY = 'abcde1234',
JWT_ALGORITHM = 'HS256'
# user/views.py
import json
from datetime import datetime, timdelta
from django.conf import settings
from django.http import JsonResponse
from django.views import View

import bcrypt
import jwt
from .models import User
from token_utils import user_token

class UserSignInView(View):
    def post(self, request):
        try:
            data = json.loads(request.body)
            username = data['username']
            pw_input = data['password']
            user = User.objects.filter(username=username).first()

            if user is None:
                return JsonResponse({"message": "INVALID_USERNAME"}, status=401)
            if bcrypt.checkpw(pw_input.encode('utf-8'),
                              user.password.encode('utf-8')):
                key = settings.SECRET_KEY
                algorithm = settings.JWT_ALGORITHM
                token = jwt.encode(
                    {
                        'iss': 'me',
                        'id': user.id,
                        'exp': datetime.utcnow() + timedelta(days=14)
                    }, key, algorithm=algorithm).decode('utf-8')

                response = JsonResponse(
                    {
                        'message': 'SUCCESS'
                    }, status=200
                )

                # 当使用本地/会话存储而不是Cookie时,只需在JsonResponse中发送令牌
                if data.get('remember_me') is not None:
                    max_age = 14*24*60*60 # 14 days
                    expires = datetime.strftime(
                        datetime.utcnow() + timedelta(seconds=max_age),
                        "%Y-%m-%d %H:%M:%S"
                    )
                    response.set_cookie(
                        'token',
                        token,
                        max_age=max_age,
                        expires=expires,
                        httponly=True
                    )
                    return response
            return JsonResponse({"message": "WRONG_PASSWORD"}, status=401)

        except KeyError as e:
            return JsonResponse({'message': f'KEY_ERROR: {e}'}, status=400)
        except ValueError as e:
            return JsonResponse({'message': f'VALUE_ERROR: {e}'}, status=400)
# token_utils.py
import json
from django.conf import settings
from django.http import JsonResponse
import jwt
from user.models import User

def user_token(func):
    def wrapper(self, request, *args, **kwargs):
        try:
            token = request.COOKIES.get('token')
            # token = request.headers.get('token')

            key = settings.SECRET_KEY
            algorithm = settings.JWT_ALGORITHM

            if token is None:
                return JsonResponse({"message": "INVALID_TOKEN"}, status=401)

            decode = jwt.decode(token, key, algorithm=algorithm)
            request.user = User.objects.get(id=decode['id'])

        except jwt.ExpiredSignatureError:
            return JsonResponse({"message": "EXPIRED_TOKEN"}, status=400)
        return func(self, request, *args, **kwargs)
    return wrapper

到此这篇关于Django中的JWT身份验证的实现的文章就介绍到这了,更多相关Django JWT身份验证内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python字符串详细介绍
May 09 Python
http请求 request失败自动重新尝试代码示例
Jan 25 Python
pandas 使用apply同时处理两列数据的方法
Apr 20 Python
Python DataFrame.groupby()聚合函数,分组级运算
Sep 18 Python
Django框架验证码用法实例分析
May 10 Python
Python 循环终止语句的三种方法小结
Jun 24 Python
PyQt5基本控件使用详解:单选按钮、复选框、下拉框
Aug 05 Python
最新2019Pycharm安装教程 亲测
Feb 28 Python
Django values()和value_list()的使用
Mar 31 Python
Python插件机制实现详解
May 04 Python
Python xml、字典、json、类四种数据类型如何实现互相转换
May 27 Python
详解基于Facecognition+Opencv快速搭建人脸识别及跟踪应用
Jan 21 Python
python开发实时可视化仪表盘的示例
Python使用scapy模块发包收包
如何用 Python 子进程关闭 Excel 自动化中的弹窗
PyTorch的Debug指南
May 07 #Python
基于Python的EasyGUI学习实践
Python列表删除重复元素与图像相似度判断及删除实例代码
使用python如何删除同一文件夹下相似的图片
May 07 #Python
You might like
php+ajax实时刷新简单实例
2015/02/25 PHP
列举PHP的Yii 2框架的开发优势
2015/07/03 PHP
php图片上传类 附调用方法
2016/05/15 PHP
PHP常用函数总结(180多个)
2016/12/25 PHP
PHP设计模式之数据访问对象模式(DAO)原理与用法实例分析
2019/12/12 PHP
使用prototype.js 的时候应该特别注意的几个问题.
2007/04/12 Javascript
Packer 3.0 JS压缩及混淆工具 下载
2007/05/03 Javascript
Ajax+Json 级联菜单实现代码
2009/10/27 Javascript
快速查找数组中的某个元素并返回下标示例
2013/09/03 Javascript
JavaScript声明变量时为什么要加var关键字
2014/09/29 Javascript
javascript类型系统 Window对象学习笔记
2016/01/07 Javascript
剖析Node.js异步编程中的回调与代码设计模式
2016/02/16 Javascript
javascript之Boolean类型对象
2016/06/07 Javascript
javascript实现根据函数名称字符串动态执行函数的方法示例
2016/12/28 Javascript
基于vue的短信验证码倒计时demo
2017/09/13 Javascript
vue移动端屏幕适配详解
2019/04/30 Javascript
详解微信UnionID作用
2019/05/15 Javascript
微信h5静默和非静默授权获取用户openId的方法和步骤
2020/06/08 Javascript
[03:17]DOTA2-DPC中国联赛1月29日Recap集锦
2021/03/11 DOTA
Python中的条件判断语句基础学习教程
2016/02/07 Python
python如何实现反向迭代
2018/03/20 Python
详解Python匿名函数(lambda函数)
2019/04/19 Python
Python通过cv2读取多个USB摄像头
2019/08/28 Python
如何安装2019Pycharm最新版本(详细教程)
2019/09/26 Python
python自动点赞功能的实现思路
2020/02/26 Python
Python grequests模块使用场景及代码实例
2020/08/10 Python
Michael Kors加拿大官网:购买设计师手袋、手表、鞋子、服装等
2019/03/16 全球购物
英国在线滑雪板和冲浪商店:The Board Basement
2020/01/11 全球购物
C语言编程练习
2012/04/02 面试题
银行开业庆典方案
2014/02/06 职场文书
护理学专业求职信
2014/06/29 职场文书
大学生党员批评与自我批评范文
2014/10/14 职场文书
贵阳市党的群众路线教育实践活动党(工)委领导班子整改方案
2014/10/26 职场文书
优秀学生主要事迹怎么写
2015/11/04 职场文书
python中__slots__节约内存的具体做法
2021/07/04 Python
分享几种python 变量合并方法
2022/03/20 Python