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中for循环详解
Jan 17 Python
python生成随机验证码(中文验证码)示例
Apr 03 Python
python实现批量获取指定文件夹下的所有文件的厂商信息
Sep 28 Python
Python中title()方法的使用简介
May 20 Python
python简单实例训练(21~30)
Nov 15 Python
django使用html模板减少代码代码解析
Dec 12 Python
python读取图片的方式,以及将图片以三维数组的形式输出方法
Jul 03 Python
pytorch打印网络结构的实例
Aug 19 Python
Python django框架输入汉字,数字,字符生成二维码实现详解
Sep 24 Python
numpy:np.newaxis 实现将行向量转换成列向量
Nov 30 Python
利用 Python ElementTree 生成 xml的实例
Mar 06 Python
pycharm中导入模块错误时提示Try to run this command from the system terminal
Mar 26 Python
python开发实时可视化仪表盘的示例
Python使用scapy模块发包收包
如何用 Python 子进程关闭 Excel 自动化中的弹窗
PyTorch的Debug指南
May 07 #Python
基于Python的EasyGUI学习实践
Python列表删除重复元素与图像相似度判断及删除实例代码
使用python如何删除同一文件夹下相似的图片
May 07 #Python
You might like
PHP面向对象分析设计的经验原则
2008/09/20 PHP
php session应用实例 登录验证
2009/03/16 PHP
部署PHP项目应该注意的几点事项分享
2013/12/20 PHP
Laravel 5框架学习之表单
2015/04/08 PHP
PHP发送AT指令实例代码
2016/05/26 PHP
JSON 客户端和服务器端的格式转换
2009/08/27 Javascript
javascript实现的使用方向键控制光标在table单元格中切换
2010/11/17 Javascript
jQuery EasyUI API 中文文档 - Pagination分页
2011/09/29 Javascript
实测jquery data()如何存值
2013/08/18 Javascript
JS数字抽奖游戏实现方法
2015/05/04 Javascript
js实现固定显示区域内自动缩放图片的方法
2015/07/18 Javascript
z-blog SyntaxHighlighter 长代码无法换行解决办法(基于jquery)
2015/11/18 Javascript
Vue.js系列之项目结构说明(2)
2017/01/03 Javascript
通过一次报错详细谈谈Point事件
2018/05/17 Javascript
webpack4的迁移的使用方法
2018/05/25 Javascript
python 将list转成字符串,中间用符号分隔的方法
2018/10/23 Python
用python代码将tiff图片存储到jpg的方法
2018/12/04 Python
Django实现auth模块下的登录注册与注销功能
2019/10/10 Python
python实现复制文件到指定目录
2019/10/16 Python
python爬虫学习笔记之Beautifulsoup模块用法详解
2020/04/09 Python
北京泡泡网网络有限公司.net面试题
2012/07/17 面试题
汽车技术服务与营销专业推荐信
2013/11/29 职场文书
仓库班组长岗位职责
2013/12/12 职场文书
企业总经理岗位职责
2014/02/13 职场文书
渔夫的故事教学反思
2014/02/14 职场文书
求职简历自我评价范例
2014/03/12 职场文书
协议书样本
2014/04/23 职场文书
我的老师教学反思
2014/05/01 职场文书
法学专业毕业生求职信
2014/06/12 职场文书
2014年终个人总结报告
2015/03/09 职场文书
公积金贷款承诺书
2015/04/30 职场文书
2015年教学管理工作总结
2015/05/20 职场文书
结婚幸福感言
2015/08/01 职场文书
旅游安全责任协议书
2016/03/22 职场文书
html+css合并表格边框的示例代码
2021/03/31 HTML / CSS
用 Python 定义 Schema 并生成 Parquet 文件详情
2021/09/25 Python