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插入数据到列表的方法
Apr 30 Python
python获取一组数据里最大值max函数用法实例
May 26 Python
python2.7 mayavi 安装图文教程(推荐)
Jun 22 Python
python中将字典形式的数据循环插入Excel
Jan 16 Python
python最小生成树kruskal与prim算法详解
Jan 17 Python
python binascii 进制转换实例
Jun 12 Python
对python 中class与变量的使用方法详解
Jun 26 Python
简单了解python filter、map、reduce的区别
Jan 14 Python
python接入支付宝的实例操作
Jul 20 Python
python3 os进行嵌套操作的实例讲解
Nov 19 Python
next在python中返回迭代器的实例方法
Dec 15 Python
Python matplotlib安装以及实现简单曲线的绘制
Apr 26 Python
python开发实时可视化仪表盘的示例
Python使用scapy模块发包收包
如何用 Python 子进程关闭 Excel 自动化中的弹窗
PyTorch的Debug指南
May 07 #Python
基于Python的EasyGUI学习实践
Python列表删除重复元素与图像相似度判断及删除实例代码
使用python如何删除同一文件夹下相似的图片
May 07 #Python
You might like
php+dbfile开发小型留言本
2006/10/09 PHP
用PHP实现多级树型菜单
2006/10/09 PHP
用mysql触发器自动更新memcache的实现代码
2009/10/11 PHP
PHP中include()与require()的区别说明
2010/03/10 PHP
在php和MySql中计算时间差的方法
2011/04/22 PHP
php类的定义与继承用法实例
2015/07/07 PHP
Laravel修改验证提示信息为中文的示例
2019/10/23 PHP
捕获浏览器关闭、刷新事件不同情况下的处理方法
2013/06/02 Javascript
javascript中动态加载js文件多种解决办法总结
2013/11/15 Javascript
Javascript设计模式理论与编程实战之简单工厂模式
2015/11/03 Javascript
jquery.validate使用详解
2016/06/02 Javascript
AngularJS中的API(接口)简单实现
2016/07/28 Javascript
JS中用三种方式实现导航菜单中的二级下拉菜单
2016/10/31 Javascript
微信小程序实现的贪吃蛇游戏【附源码下载】
2018/01/03 Javascript
Node.js API详解之 repl模块用法实例分析
2020/05/25 Javascript
Jquery $.map使用方法实例详解
2020/09/01 jQuery
jQuery是用来干什么的 jquery其实就是一个js框架
2021/02/04 jQuery
[03:23:49]2016.12.17日完美“圣”典全回顾
2016/12/19 DOTA
[01:00:14]DOTA2官方TI8总决赛纪录片 真视界True Sight
2019/01/16 DOTA
[56:48]FNATIC vs EG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
基于Python实现的百度贴吧网络爬虫实例
2015/04/17 Python
python实现稀疏矩阵示例代码
2017/06/09 Python
Python两个字典键同值相加的几种方法
2019/03/05 Python
python获取Pandas列名的几种方法
2019/08/07 Python
python随机生成库faker库api实例详解
2019/11/28 Python
python给视频添加背景音乐并改变音量的具体方法
2020/07/19 Python
Pytho爬虫中Requests设置请求头Headers的方法
2020/09/22 Python
美国鲍勃商店:Bob’s Stores
2018/07/22 全球购物
美国迪克体育用品商店:DICK’S Sporting Goods
2018/07/24 全球购物
英国书籍、CD、DVD和游戏的第一道德零售商:Awesome Books
2020/02/22 全球购物
党员创先争优承诺书
2014/03/26 职场文书
十佳党员事迹材料
2014/08/28 职场文书
大学辅导员述职报告
2015/01/10 职场文书
员工升职自荐信
2015/03/27 职场文书
高中升旗仪式主持词
2015/07/03 职场文书
Python用tkinter实现自定义记事本的方法详解
2022/03/31 Python