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的Bottle框架中返回静态文件和JSON对象的方法
Apr 30 Python
Python整型运算之布尔型、标准整型、长整型操作示例
Jul 21 Python
快速查询Python文档方法分享
Dec 27 Python
在pycharm上mongodb配置及可视化设置方法
Nov 30 Python
padas 生成excel 增加sheet表的实例
Dec 11 Python
Python实现网站表单提交和模板
Jan 15 Python
python中时间、日期、时间戳的转换的实现方法
Jul 06 Python
python twilio模块实现发送手机短信功能
Aug 02 Python
django与vue的完美结合_实现前后端的分离开发之后在整合的方法
Aug 12 Python
python pyinstaller打包exe报错的解决方法
Nov 02 Python
基于python实现matlab filter函数过程详解
Jun 08 Python
详解Python描述符的工作原理
Jun 11 Python
python开发实时可视化仪表盘的示例
Python使用scapy模块发包收包
如何用 Python 子进程关闭 Excel 自动化中的弹窗
PyTorch的Debug指南
May 07 #Python
基于Python的EasyGUI学习实践
Python列表删除重复元素与图像相似度判断及删除实例代码
使用python如何删除同一文件夹下相似的图片
May 07 #Python
You might like
PHP+JS无限级可伸缩菜单详解(简单易懂)
2007/01/02 PHP
Fatal error: Call to undefined function curl_init()解决方法
2010/04/09 PHP
PHP-CGI进程CPU 100% 与 file_get_contents 函数的关系分析
2011/08/15 PHP
基于php中使用excel的简单介绍
2013/08/02 PHP
php自动提交表单的方法(基于fsockopen与curl)
2016/05/09 PHP
Zend Framework入门教程之Zend_Session会话操作详解
2016/12/08 PHP
javascript prototype原型操作笔记
2009/12/07 Javascript
一段实现页面上的图片延时加载的js代码
2010/02/11 Javascript
Jquery从头学起第四讲 jquery入门教程
2010/08/01 Javascript
javascript延时加载之defer测试
2012/12/28 Javascript
Jquery解析Json格式数据过程代码
2014/10/17 Javascript
JavaScript中的分号插入机制详细介绍
2015/02/11 Javascript
Jquery全选与反选点击执行一次的解决方案
2015/08/14 Javascript
JavaScript知识点总结(十)之this关键字
2016/05/31 Javascript
Bootstrap学习笔记之js组件(4)
2016/06/12 Javascript
NodeJS遍历文件生产文件列表功能示例
2017/01/22 NodeJs
vue.js使用代理和使用Nginx来解决跨域的问题
2018/02/03 Javascript
[00:48]DOTA2国际邀请赛公开赛报名开始 扫码开启逐梦之旅
2018/06/06 DOTA
python使用Flask框架获取用户IP地址的方法
2015/03/21 Python
深入解析Python中函数的参数与作用域
2016/03/20 Python
python爬虫入门教程--正则表达式完全指南(五)
2017/05/25 Python
python将文本中的空格替换为换行的方法
2018/03/19 Python
浅谈Python 多进程默认不能共享全局变量的问题
2019/01/11 Python
详解Python字典的操作
2019/03/04 Python
Python 打印自己设计的字体的实例讲解
2021/01/04 Python
Pycharm 跳转回之前所在页面的操作
2021/02/05 Python
详解HTML5中的元素与元素
2015/08/17 HTML / CSS
整理HTML5的一些新特性与Canvas的常用属性
2016/01/29 HTML / CSS
记一次高分屏下canvas模糊问题
2020/02/17 HTML / CSS
数据管理员的自我评价分享
2013/11/15 职场文书
竞选村长演讲稿
2014/04/28 职场文书
敬老院标语
2014/06/27 职场文书
2014年圣诞节寄语
2014/12/08 职场文书
村党总支部公开承诺书2016
2016/03/25 职场文书
详解Laravel服务容器的优势
2021/05/29 PHP
浅谈Java父子类加载顺序
2021/08/04 Java/Android