首页 > 其他分享 >CSRF校验策略及装饰器和auth认证模块

CSRF校验策略及装饰器和auth认证模块

时间:2022-12-23 19:57:04浏览次数:39  
标签:username return CSRF views request 校验 auth csrf

目录

csrf跨站请求伪造

钓鱼网站:模仿一个正规的网站 让用户在该网站上做操作 但是操作的结果会影响到用户正常的网站账户,但是其中有一些猫腻
eg:英语四六级考试需要网上先缴费,但是你会发现卡里的钱扣了但是却交到了一个莫名其妙的账户,并不是真正的四六级官方账户

模拟钓鱼网站案例:转账案例
真实网站:
urls.py
# 转账接口
    path('transfer/',views.transfer_func),

views.py:
def transfer_func(request):
    if request.method == 'POST':
        username=request.POST.get('username')
        target_name = request.POST.get('target_name')
        money = request.POST.get('money')
        print(f'{username}给{target_name}转了{money}元')
    return render(request,'transferPage.html')
transferPage.html:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>我是真的网站</h1>
<form action="" method="post">
    <p>用户名:
        <input type="text" name="username">
    </p>
    <p>他人名:
        <input type="text" name="target_name">
    </p>
    <p>转账金额:
        <input type="text" name="money">
    </p>
    <input type="submit" value="提交">
</form>
</body>
</html>

假网站:
urls.py
# 转账接口
    path('transfer/',views.transfer_func),

views.py:
def transfer_func(request):
	return render(request,'transferPage.html')
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>我是假的网站</h1>
    <form action="http://127.0.0.1:8000/transfer/" method="post">
        <p>用户名:
            <input type="text" name="username">
        </p>
        <p>他人名:
            <input type="text" >
            <input type="text"  name="target_name" value="黑客winter" style="display: none">
        </p>
        <p>转账金额:
            <input type="text" name="money">
        </p>
        <input type="submit" value="提交">
    </form>
</body>
</html>

csrf校验策略

在提交数据的位置添加唯一标识

1.form表单csrf策略:
	form表单内部添加 {% csrf_token %}
2.ajax请求csrf策略
	// 方式1:自己动手取值 较为繁琐
   {#data:{'csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()},#}
   // 方式2:利用模板语法自动获取(一定要用引号引起来)
   {#data:{ 'csrfmiddlewaretoken':'{{ csrf_token }}','username':'jason'},#}
   // 方式3:直接引入一个js脚本即可(官网提供的)
 	参考:https://www.cnblogs.com/Dominic-Ji/p/9234099.html

csrf相关装饰器

from django.views.decorators.csrf import csrf_exempt,csrf_protect#导入方法
csrf_exempt         #整个django项目都校验csrf,某个视图函数\类不需要进行csrf校验
csrf_protect        #整个django项目都不校验csrf,某个视图函数\类需要进行csrf校验

FBV:

#FBV使用直接加就行
@csrf_exempt
def index(request):
    pass
"""把csrf_exempt装饰器直接加到index函数中,使该函数不需要经过csrf验证(配置文件开启csrf验证)

FBV:

#FBV使用直接加就行
@csrf_protect
def index(request):
    pass
"""把csrf_protect装饰器直接加到index函数中,使该函数需要经过csrf验证(配置文件关闭csrf验证)

FBV:
方式1:对类中某个方法生效
from django import views
from django.utils.decorators import  method_decorator
class MyView(views.View):
    @method_decorator(csrf_protect)
    def post(self,request):
        return HttpResponse('from cvb post view')
#配置文件csrf关闭,类中post方法需要csrf验证

方式2:对类中某个方法生效
from django import views
from django.utils.decorators import  method_decorator
@method_decorator(csrf_protect,name='post')
class MyView(views.View):
    def post(self,request):
        return HttpResponse('from cvb post view')
#配置文件csrf关闭,类中post方法需要csrf验证

方式3:对类中所有方法生效
from django.views.decorators.csrf import csrf_exempt,csrf_protect

from django import views
from django.utils.decorators import  method_decorator
class MyView(views.View):
    @method_decorator(csrf_protect)
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request,*args,**kwargs)
    def post(self,request):
        return HttpResponse('from cvb post view')

注意有一个装饰器是特例只能有一种添加方式>>>:csrf_exempt
只有在dispatch方法添加才会生效,也就是方式3,类所有方法

auth认证模块

前戏:django自带一个admin路由 但是需要我们提供管理员账号和密码
如果想要使用admin后台管理 需要先创建表 然后创建管理员账号
直接执行数据库迁移命令即可产生默认的auth_user表 该表就是admin后台管理默认的认证表
1.创建超级管理员
	python38 manage.py createsuperuser

基于auth_user表编写用户相关的各项功能
	登录、校验用户是否登录、修改密码、注销登录等

image

auth认证相关模块及操作

用户注册

urls.py:
# auth用户注册
path('register/',views.register_func),

views.py:
from django.contrib import auth
from django.contrib.auth.models import User
def register_func(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password= request.POST.get('password')
        # 1.校验用户名是否存在
        res = User.objects.filter(username=username)
        if res:
            return HttpResponse('用户名已存在')
        # 2.注册用户
        # User.objects.create(username=username,password=password) # create方法不可以使用 密码不加密
        User.objects.create_user(username=username,password=password) # create_user方法会自动对密码加密
    return render(request,'registerPage.html')

registerPage.html:
<body>
<form action="" method="post">
    {% csrf_token %}
    <p>username:
        <input type=" text" name="username">
    </p>
    <p>password:
        <input type="text" name="password">
    </p>
    <input type="submit" value="注册">
</form>
</body>
</html>

用户登录

urls.py:
# auth用户登录
path('login/',views.login_func),

views.py:
def login_func(request):
    print(request.user) # 打印当前登录用户
    print(request.user.is_authenticated) # 判断当前用户是否已登录
    if request.method == 'POST':
        username = request.POST.get('username')
        password= request.POST.get('password')
        # 1.校验用户名和密码是否正确(不分开校验) 自己无法比对密码 必须要使用auth模块提供的方法才可以
        user_obj = auth.authenticate(request,username=username,password=password) # 用户名密码正确之后返回的是数据对象
        if user_obj:
            # 2.用户登录成功(返回给客户端登录的凭证、令牌、随机字符串)
            auth.login(request,user_obj)  # 自动操作django_session表
            return HttpResponse('登录成功')
            '''当执行完上述操作后 我们可以通过request.user直接获取当前登录的用户对象数据'''
    return render(request,'loginPage.html')

loginPage.html:
<body>
<form action="" method="post">
    {% csrf_token %}
    <p>username:
        <input type=" text" name="username">
    </p>
    <p>password:
        <input type="text" name="password">
    </p>
    <input type="submit" value="登录">
</form>
</body>
</html>

网站首页
模拟博客园,登录显示用户名,没有登录显示注册和登录

urls.py:
# 网站首页
path('home/',views.home_func),

views.py:
def home_func(request):
    return render(request,'homePage.html',locals())

homePage.html:
<body>
    {% if request.user.is_authenticated %}
            <h1>{{ request.user.username }}</h1>
        {% else %}
            <a href="">注册</a>
            <a href="">登录</a>
    {% endif %} 
</body>
</html>

校验用户是否登录装饰器

方式1:局部配置
urls.py:
# index页面 只有登录的用户才可以看
path('index/',views.index_func),

from django.contrib.auth.decorators import login_required
@login_required(login_url='/login/')  #可以明确指定用户没有登录之后跳转到哪个地址
def index_func(request):
    return HttpResponse('index页面 只有登录的用户才可以查看')

方式2:全局配置
settings.py:
LOGIN_URL = '/login/'
@login_required
def index_func(request):
    return HttpResponse('index页面 只有登录的用户才可以查看')

ps:当局部和全局产生冲突的话,以局部为准

修改密码

urls.py:
# auth用户修改密码
path('set_pwd/',views.set_pwd_func),

views.py:
@login_required
def set_pwd_func(request):
    if request.method == 'POST':
        old_pwd = request.POST.get('old_pwd')
        new_pwd = request.POST.get('new_pwd')
        confirm_pwd = request.POST.get('confirm_pwd')
        if not new_pwd == confirm_pwd:
            return HttpResponse('两次密码不一致')
        # 1.判断原密码是否正确
        is_right=request.user.check_password(old_pwd)
        if not is_right:
            return HttpResponse('原密码不正确')
        #2.修改密码
        request.user.set_password(new_pwd)
        request.user.save()  # 一定要保存 否则不会修改
    return render(request,'setPwdPage.html')

setPwdPage.html:
<body>
<form action="" method="post">
    {% csrf_token %}
    <p>原密码:
        <input type="text" name="old_pwd">
    </p>
    <p>新密码:
        <input type="text" name="new_pwd">
    </p>
    <p>确认密码:
        <input type="text" name="confirm_pwd">
    </p>
    <input type="submit" value="提交">
</form>
</body>
</html>

注销登录

urls.py:
# auth用户退出登录
path('logout/',views.logout_func),

views.py:
@login_required
def logout_func(request):
    auth.logout(request)
    return HttpResponse('用户退出登录')

扩展auth_user表

标签:username,return,CSRF,views,request,校验,auth,csrf
From: https://www.cnblogs.com/winter-yu1989/p/17001497.html

相关文章

  • 二、深入理解OAuth 2.0
    目录一、为什么会出现OAuth二、名词定义三、OAuth的思路四、运行流程五、客户端获取授权模式1、授权码模式2、简化模式3、密码模式4、客户端模式六、更新令牌其它OAu......
  • 一、OAuth 2.0 的一个简单解释
    OAuth2.0是目前最流行的授权机制,用来授权第三方应用,获取用户数据。这个标准比较抽象,使用了很多术语,初学者不容易理解。其实说起来并不复杂,下面我就通过一个简单的类......
  • sqlserver/System.Data.SqlClient.SqlException (0x80131904): 用户 'NT AUTHORITY\I
    本人最近学习XAF框架项目,在本地运行可以连接到数据库,发布后无法连接,抛出用户'NTAUTHORITY\IUSR'登录失败问题截图:  问题原因:数据库连接使用的window身份验证时,W......
  • auth认证模块
    auth认证模块auth认证前瞻django自带一个admin路由,但是需要我们提供管理员账号和密码。如果想要使用admin后台管理,需要先创建表,然后创建管理员账号。不用手写模型表,dj......
  • CSRF校验及CBV加装装饰器
    CSRF校验及CBV加装装饰器csrf跨站请求伪造我们的网站在提交表单时,是通过post请求朝一个网站提交信息,这个网站的服务端可以通过request.POST拿到的目标数据,那么就存在这么......
  • 12月23日内容总结——csrf跨站请求伪造、校验策略、相关装饰器,auth认证模块及相关操作
    目录一、csrf跨站请求伪造二、csrf校验策略三、csrf相关装饰器四、auth认证模块五、auth认证相关模块及操作六、扩展auth_user表七、作业一、csrf跨站请求伪造钓鱼网站:......
  • django、中间件、cookie、session、csrf
    目录今日内容详细今日内容详细django中间件三个了解的方法基于django中间件的功能设计cookie与session简介django操作cookiedjango操作session今日内容详细django中间件......
  • 基于 Traefik 的 Basic Auth 配置
    前言Traefik是一个现代的HTTP反向代理和负载均衡器,使部署微服务变得容易。Traefik可以与现有的多种基础设施组件(Docker、Swarm模式、Kubernetes、Marathon、Consul、Etcd......
  • 基于 Traefik 的 Basic Auth 配置
    前言Traefik是一个现代的HTTP反向代理和负载均衡器,使部署微服务变得容易。Traefik可以与现有的多种基础设施组件(Docker、Swarm模式、Kubernetes、Marathon、Consul、Etcd......
  • 【深度思考】如何优雅的校验参数?
    在日常的开发工作中,为了保证落库数据的完整性,参数校验绝对是必不可少的一部分,本篇文章就来讲解下在项目中该如何优雅的校验参数。假设有一个新增学员的接口,一般第一步我们......