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的时间模块datetime详解
Apr 17 Python
Python简单计算文件MD5值的方法示例
Apr 11 Python
Django中反向生成models.py的实例讲解
May 30 Python
在OpenCV里实现条码区域识别的方法示例
Dec 04 Python
解决Python列表字符不区分大小写的问题
Dec 19 Python
pycharm软件实现设置自动保存操作
Jun 08 Python
python实现批处理文件
Jul 28 Python
python各种excel写入方式的速度对比
Nov 10 Python
使用python爬取抖音app视频的实例代码
Dec 01 Python
Python 无限级分类树状结构生成算法的实现
Jan 21 Python
python process模块的使用简介
May 14 Python
python图像处理 PIL Image操作实例
Apr 09 Python
python开发实时可视化仪表盘的示例
Python使用scapy模块发包收包
如何用 Python 子进程关闭 Excel 自动化中的弹窗
PyTorch的Debug指南
May 07 #Python
基于Python的EasyGUI学习实践
Python列表删除重复元素与图像相似度判断及删除实例代码
使用python如何删除同一文件夹下相似的图片
May 07 #Python
You might like
php禁用cookie后session设置方法分析
2016/10/19 PHP
PHP实现无限分类的实现方法
2016/11/14 PHP
PHP实现文件下载【实例分享】
2017/04/28 PHP
使两个iframe的高度与内容自适应,且相等
2006/11/20 Javascript
很多人都是用下面的js刷新站IP和PV
2008/09/05 Javascript
浅说js变量
2011/05/25 Javascript
浅谈javascript的原型继承
2012/07/25 Javascript
js动态删除div元素基本思路及实现代码
2014/05/08 Javascript
jQuery+css3动画属性制作猎豹浏览器宽屏banner焦点图
2015/03/16 Javascript
分享五个有用的jquery小技巧
2015/10/08 Javascript
js点击文本框后才加载验证码实例代码
2015/10/20 Javascript
浅谈javascript的call()、apply()、bind()的用法
2016/02/21 Javascript
Angular.js中处理页面闪烁的方法详解
2017/03/09 Javascript
Vue异步组件使用详解
2017/04/08 Javascript
Vue组件通信之Bus的具体使用
2017/12/28 Javascript
浅谈webpack4 图片处理汇总
2018/09/12 Javascript
微信小程序利用button控制条件标签的变量问题
2020/03/15 Javascript
微信小程序实现组件顶端固定或底端固定效果(不随滚动而滚动)
2020/04/09 Javascript
vue实现前端列表多条件筛选
2020/10/26 Javascript
python re正则表达式模块(Regular Expression)
2014/07/16 Python
Django实现全文检索的方法(支持中文)
2018/05/14 Python
解决python selenium3启动不了firefox的问题
2018/10/13 Python
python读取配置文件方式(ini、yaml、xml)
2020/04/09 Python
详解Python的爬虫框架 Scrapy
2020/08/03 Python
html5 canvas实现给图片添加平铺水印
2019/08/20 HTML / CSS
La Senza官网:北美顶尖性感内衣品牌
2018/08/03 全球购物
初三化学教学反思
2014/01/23 职场文书
英语教学随笔感言
2014/02/20 职场文书
秋天的雨教学反思
2014/04/27 职场文书
计算机专业自荐信范文
2014/05/28 职场文书
民族精神月活动总结
2014/08/28 职场文书
爱岗敬业事迹材料
2014/12/24 职场文书
英语教师个人总结
2015/02/09 职场文书
行政助理岗位职责范本
2015/04/11 职场文书
《中华上下五千年》读后感3篇
2019/11/29 职场文书
Spring Boot接口定义和全局异常统一处理
2022/04/20 Java/Android