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删除指定目录下过期文件的2个脚本分享
Apr 10 Python
Python中尝试多线程编程的一个简明例子
Apr 07 Python
浅谈Python对内存的使用(深浅拷贝)
Jan 17 Python
Python中max函数用于二维列表的实例
Apr 03 Python
python pycurl验证basic和digest认证的方法
May 02 Python
利用Python读取txt文档的方法讲解
Jun 23 Python
使用python读取.text文件特定行的数据方法
Jan 28 Python
Python字符编码转码之GBK,UTF8互转
Feb 09 Python
python中二分查找法的实现方法
Dec 06 Python
Python .py生成.pyd文件并打包.exe 的注意事项说明
Mar 04 Python
Python爬取英雄联盟MSI直播间弹幕并生成词云图
Jun 01 Python
Python3使用Qt5来实现简易的五子棋小游戏
May 02 Python
python开发实时可视化仪表盘的示例
Python使用scapy模块发包收包
如何用 Python 子进程关闭 Excel 自动化中的弹窗
PyTorch的Debug指南
May 07 #Python
基于Python的EasyGUI学习实践
Python列表删除重复元素与图像相似度判断及删除实例代码
使用python如何删除同一文件夹下相似的图片
May 07 #Python
You might like
php中二维数组排序问题方法详解
2015/08/28 PHP
PHP+Mysql+jQuery实现发布微博程序 php篇
2015/10/15 PHP
PHP+MySQL使用mysql_num_rows实现模糊查询图书信息功能
2018/05/31 PHP
PHP实现获取毫秒时间戳的方法【使用microtime()函数】
2019/03/01 PHP
javascript之卸载鼠标事件的代码
2007/05/14 Javascript
使用ExtJS技术实现的拖动树结点
2010/08/05 Javascript
JavaScript 选中文字并响应获取的实现代码
2011/08/28 Javascript
javascript实现简单的省市区三级联动
2015/05/14 Javascript
JS实现可点击展开与关闭的左侧广告代码
2015/09/02 Javascript
jQuery实现ajax调用WCF服务的方法(附带demo下载)
2015/12/04 Javascript
两种方法解决javascript url post 特殊字符转义 + & #
2016/04/13 Javascript
JS实现获取剪贴板内容的方法
2016/06/21 Javascript
Node.js中防止错误导致的进程阻塞的方法
2016/08/11 Javascript
微信小程序 获取设备信息 API实例详解
2016/10/02 Javascript
js多个物体运动功能实例分析
2016/12/20 Javascript
详解Python中logging日志模块在多进程环境下的使用
2016/12/26 Javascript
使用js实现单链解决前端队列问题的方法
2020/02/03 Javascript
vue实现评价星星功能
2020/06/30 Javascript
JavaScript实现弹出窗口效果
2020/12/09 Javascript
十个Python程序员易犯的错误
2015/12/15 Python
python3读取MySQL-Front的MYSQL密码
2017/05/03 Python
python3模块smtplib实现发送邮件功能
2018/05/22 Python
python+POP3实现批量下载邮件附件
2018/06/19 Python
Python+OpenCV图片局部区域像素值处理改进版详解
2019/01/23 Python
python opencv判断图像是否为空的实例
2019/01/26 Python
keras多显卡训练方式
2020/06/10 Python
如何使用Django Admin管理后台导入CSV
2020/11/06 Python
Ratchet 模态框的实现
2020/08/19 HTML / CSS
W Hamond官网:始于1979年的钻石专家
2020/07/20 全球购物
面向游戏玩家和书呆子的极客订阅盒:Loot Crate
2020/11/25 全球购物
学院书画协会部门职责
2013/11/28 职场文书
男方父母婚礼答谢词
2014/01/25 职场文书
教学改革实施方案
2014/03/31 职场文书
岗位标兵事迹材料
2014/05/17 职场文书
文明好少年事迹材料
2014/08/19 职场文书
关于读书的演讲稿600字
2014/08/27 职场文书