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通过加号运算符操作列表的方法
Jul 28 Python
Python数据分析之双色球统计两个红和蓝球哪组合比例高的方法
Feb 03 Python
python中数据爬虫requests库使用方法详解
Feb 11 Python
详谈Python中列表list,元祖tuple和numpy中的array区别
Apr 18 Python
python实现批量注册网站用户的示例
Feb 22 Python
浅谈Python编程中3个常用的数据结构和算法
Apr 30 Python
python pyinstaller 加载ui路径方法
Jun 10 Python
通过PHP与Python代码对比的语法差异详解
Jul 10 Python
centos7之Python3.74安装教程
Aug 15 Python
flask框架渲染Jinja模板与传入模板变量操作详解
Jan 25 Python
Python定义函数实现累计求和操作
May 03 Python
Selenium及python实现滚动操作多种方法
Jul 21 Python
python开发实时可视化仪表盘的示例
Python使用scapy模块发包收包
如何用 Python 子进程关闭 Excel 自动化中的弹窗
PyTorch的Debug指南
May 07 #Python
基于Python的EasyGUI学习实践
Python列表删除重复元素与图像相似度判断及删除实例代码
使用python如何删除同一文件夹下相似的图片
May 07 #Python
You might like
星际争霸 Starcraft 秘技补丁
2020/03/14 星际争霸
数据库中排序的对比及使用条件详解
2012/02/23 PHP
php微信公众开发之获取周边酒店信息的方法
2014/12/22 PHP
PHP控制前台弹出对话框的实现方法
2016/08/21 PHP
php使用pecl方式安装扩展操作示例
2019/08/12 PHP
直接生成打开窗口代码,不必下载
2008/05/14 Javascript
Javascript模块模式分析
2008/05/16 Javascript
Javascript封装DOMContentLoaded事件实例
2014/06/12 Javascript
js简单时间比较的方法
2016/08/02 Javascript
vuejs2.0运用原生js实现简单的拖拽元素功能示例
2017/02/24 Javascript
基于Vue2.0的分页组件
2017/03/16 Javascript
学习使用Bootstrap页面排版样式
2017/05/11 Javascript
vue 根据数组中某一项的值进行排序的方法
2018/08/30 Javascript
vue 通过 Prop 向子组件传递数据的实现方法
2020/10/30 Javascript
python多线程编程中的join函数使用心得
2014/09/02 Python
python下调用pytesseract识别某网站验证码的实现方法
2016/06/06 Python
Python基于list的append和pop方法实现堆栈与队列功能示例
2017/07/24 Python
Python使用ConfigParser模块操作配置文件的方法
2018/06/29 Python
Python+OpenCV实现实时眼动追踪的示例代码
2019/11/11 Python
Python完全识别验证码自动登录实例详解
2019/11/24 Python
pytorch 实现删除tensor中的指定行列
2020/01/13 Python
python右对齐的实例方法
2020/07/05 Python
python批量生成条形码的示例
2020/10/10 Python
基于Python爬取股票数据过程详解
2020/10/21 Python
基于OpenCV的网络实时视频流传输的实现
2020/11/15 Python
波兰在线体育用品商店:Hop-Sport.pl
2019/07/23 全球购物
Piercing Pagoda官网:耳环、戒指、项链、手链等
2020/09/28 全球购物
请问如下代码执行后a和b的值分别是什么
2016/05/05 面试题
AJax面试题
2014/11/25 面试题
学校课外活动总结
2014/05/08 职场文书
药剂专业毕业生求职信
2014/06/24 职场文书
劳资员岗位职责
2015/02/13 职场文书
岗位职责范本大全
2015/02/26 职场文书
公司年会主持词范文!
2019/05/07 职场文书
SQL实现LeetCode(196.删除重复邮箱)
2021/08/07 MySQL
MySQL GTID复制的具体使用
2022/05/20 MySQL