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的Flask框架下使用sqlalchemy库的简单教程
Apr 09 Python
python实现上传下载文件功能
Nov 19 Python
详解python的ORM中Pony用法
Feb 09 Python
在PyCharm中批量查找及替换的方法
Jan 20 Python
Python定义函数功能与用法实例详解
Apr 08 Python
对PyQt5中的菜单栏和工具栏实例详解
Jun 20 Python
python机器学习库scikit-learn:SVR的基本应用
Jun 26 Python
pytorch中交叉熵损失(nn.CrossEntropyLoss())的计算过程详解
Jan 02 Python
django中cookiecutter的使用教程
Dec 03 Python
Python中的流程控制详解
Feb 18 Python
python 如何在 Matplotlib 中绘制垂直线
Apr 02 Python
python中的plt.cm.Paired用法说明
May 31 Python
python开发实时可视化仪表盘的示例
Python使用scapy模块发包收包
如何用 Python 子进程关闭 Excel 自动化中的弹窗
PyTorch的Debug指南
May 07 #Python
基于Python的EasyGUI学习实践
Python列表删除重复元素与图像相似度判断及删除实例代码
使用python如何删除同一文件夹下相似的图片
May 07 #Python
You might like
磨咖啡豆的密诀
2021/03/03 冲泡冲煮
apache mysql php 源码编译使用方法
2012/05/03 PHP
PHP中替换换行符的几种方法小结
2012/10/15 PHP
根据IP的地址,区分不同的地区,查看不同的网站页面的js代码
2013/02/26 Javascript
解析offsetHeight,clientHeight,scrollHeight之间的区别
2013/11/20 Javascript
jquery ajax中使用jsonp的限制解决方法
2013/11/22 Javascript
js实现用户注册协议倒计时的方法
2015/01/21 Javascript
jQuery实现的倒计时效果实例小结
2016/04/16 Javascript
探寻JavaScript中this指针指向
2016/04/23 Javascript
Ajax的概述与实现过程
2016/11/18 Javascript
Vue项目组件化工程开发实践方案
2018/01/09 Javascript
VUE-Table上绑定Input通过render实现双向绑定数据的示例
2018/08/27 Javascript
Vue中JS动画与Velocity.js的结合使用
2019/02/13 Javascript
javascript实现自由编辑图片代码详解
2019/06/21 Javascript
javascript前端和后台进行数据交互方法示例
2020/08/07 Javascript
wxpython 最小化到托盘与欢迎图片的实现方法
2014/06/09 Python
Python中的 ansible 动态Inventory 脚本
2020/01/19 Python
利用python画出AUC曲线的实例
2020/02/28 Python
Python如何向SQLServer存储二进制图片
2020/06/08 Python
Python Serial串口基本操作(收发数据)
2020/11/06 Python
python 用opencv实现霍夫线变换
2020/11/27 Python
HTML5实现预览本地图片
2016/02/17 HTML / CSS
html5 canvas手势解锁源码分享
2020/01/07 HTML / CSS
Linux内核的同步机制是什么?主要有哪几种内核锁
2016/07/11 面试题
总经理岗位职责
2013/11/09 职场文书
高校自主招生自荐信
2013/12/09 职场文书
三年级小学生评语
2014/04/22 职场文书
廉洁家庭事迹材料
2014/05/15 职场文书
2014年污水处理厂工作总结
2014/12/19 职场文书
求职简历自我评价怎么写
2015/03/10 职场文书
雾霾停课通知
2015/04/24 职场文书
离婚起诉书怎么写
2015/05/19 职场文书
运动会开幕式通讯稿
2015/07/18 职场文书
《狼牙山五壮士》教学反思
2016/02/17 职场文书
详解CSS开发过程中的20个快速提升技巧
2021/05/21 HTML / CSS
Python 发送SMTP邮件的简单教程
2021/06/24 Python