CSRF操作于Auth认证模块(Auth_user表切换|中间件设计项目功能)

一、CSRF跨站请求伪造

		简介
			首先我们看到名称伪造就发现有端倪 CSRF跨站伪造 我们可以简单的理解成钓鱼网站 
			钓鱼网站会拥有一个跟银行app网页一样的界面 当我们输入转账人的时候确定转账
			这个时候钓鱼网站就会把转账人收款的账号修改成自己的 所以有些网站就是这种黑钱的方法
			
		模拟
			一台计算机上面设置两个服务端不同的端口启动 钓鱼网站提交地址改为正规网站的地址
			
		策防
			CSRF策略:通过在返回的页面上添加一个独一无二的标识信息 从标识信息中查看返回的信息是否一致 如果不一致则说明有人截取了该信息
			正规网站发现信息不一致则拒绝接收 此现象叫做403Forbidden 与此相关的策略就是我们中间件中的之前被注释的一行代码
			MIDDLEWARE = [django.middleware.csrf.CsrfViewMiddleware]

在这里插入图片描述

	Fake
		    <form method="post" action="http://127.0.0.1:8000/real/">
		        <p>username:<input type="text" name="username"></p>
		        <p>target_user<input type="text"><input type="text" name="target_user" value="土匪" style="display: none"></p>
		        <p>Money:<input type="text" name="money"></p>
		        <input type="submit">
		    </form>

	real.views
			def real_html(request):
			    if request.method == 'POST':
			        username = request.POST.get('username')
			        target_user = request.POST.get('target_user')
			        money = request.POST.get('money')
			        print(f'用户{username}{target_user}转账了{money}元!!!')
			    return render(request, 'real.html')

二、CSRF操作

		如果我们想解决这个问题 就要针对Post请求 涉及到Post请求当前博客中提到过form表单以及Ajax

		Post
			post请求如果想阻止发生这种事情的话很简单 把注释打开 只要加上模版语法{%. csrf_token %}
			我们点击右键检查会发现多一行input是由csrf创建的 当我们刷新一次页面就会获得不一样的字符串标识信息
			这个时候我们真正的网站转账是可以通过 但是钓鱼网站就会显示403Forbidden
			
		    <form method="post">
		        {% csrf_token %}
		        <p>username:<input type="text" name="username"></p>
		        <p>target_user<input type="text" name="target_user"></p>
		        <p>Money:<input type="text" name="money"></p>
		        <input type="submit">
		    </form>

		Ajax
			方式1
				先编写csrf模板语法 然后利用标签查找和值获取 手动添加 需要添加 {% csrf_token %}
				data:{'username':'James','csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()},
				
			方法2
				直接利用模板语法即可 不需要添加{% csrf_token %}
				data:{'username':'James','csrfmiddlewaretoken':'{{ csrf_token }}'},
				
			方式3
				直接使用JS脚本 拓展性最高
				<script src="/static/csrf.js"></script>
				
				function getCookie(name) {
				    var cookieValue = null;
				    if (document.cookie && document.cookie !== '') {
				        var cookies = document.cookie.split(';');
				        for (var i = 0; i < cookies.length; i++) {
				            var cookie = jQuery.trim(cookies[i]);
				            // Does this cookie string begin with the name we want?
				            if (cookie.substring(0, name.length + 1) === (name + '=')) {
				                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
				                break;
				            }
				        }
				    }
				    return cookieValue;
				}
				var csrftoken = getCookie('csrftoken');
				
				function csrfSafeMethod(method) {
				  // these HTTP methods do not require CSRF protection
				  return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
				}
				
				$.ajaxSetup({
				  beforeSend: function (xhr, settings) {
				    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
				      xhr.setRequestHeader("X-CSRFToken", csrftoken);
				    }
				  }
				});

在这里插入图片描述
在这里插入图片描述

三、CSRF装饰器相关操作

		现在我们知道怎么操作CSRF但是当整个网站默认都不校验csrf 但是局部视图函数需要校验 如何处理
		当整个网站默认都校验csrf 但是局部视图函数不需要校验 如何处理? 这个时候就需要使用到Django提供的两个装饰器
		from django.views.decorators.csrf import csrf_protect, csrf_exempt
		csrf_protect表示检验csrf		csrf_exmpt表示不检验csrf
		FBV
		----------------------------------------------
			'''首先将中间件中的注释掉django.middleware.csrf.CsrfViewMiddleware'''
			html
				<form action="/fbv/" method="post"> # 直接发送post请求
				    <input type="submit">
				</form>
				
			'''如果想让检测加上装饰器则是csrf_protect 不想检测就是csrf_exempt'''
			views
				from django.views.decorators.csrf import csrf_protect, csrf_exempt
				@csrf_protect     # 检验csrf
				def fbv(request):
				    if request.method == 'POST':
				        return HttpResponse('我是FBV!!!!')
				    return render(request, 'fbv.html')
			    
		-------------------------------------------------
		CBV
			'''针对CBV不能直接在方法上添加装饰器 需要借助于专门添加装饰器的方法'''
			方式1
				html
					<form action="http://127.0.0.1:8000/fbv/" method="post">
					    <input type="submit">
					</form>
				views
					from django.utils.decorators import method_decorator
					class MyFbv(views.View):
					    def get(self, request):
					        return HttpResponse('I From GET!!!')
					        
					    @method_decorator(csrf_protect)	 # 加上Csfr验证
					    def post(self, request):
					        return HttpResponse('I Form POST!!!')
					        
			方式2
					from django.utils.decorators import method_decorator
					@method_decorator(csrf_protect, name='post')	# 指定对象
					class MyFbv(views.View):
					    def get(self, request):
					        return HttpResponse('I From GET!!!')
					        
					    def post(self, request):
					        return HttpResponse('I Form POST!!!')
					        
			方式3	
					from django.utils.decorators import method_decorator
					class MyFbv(views.View):	# 通过影响类中的dispatch方法添加一个csfr方法
				    @method_decorator(csrf_protect)
				    def dispatch(self, request, *args, **kwargs):
				        super(MyFbv, self).dispatch(request, *args, **kwargs)
				
				    def get(self, request):
				        return HttpResponse('I From GET!!!')
				
				    def post(self, request):
				        return HttpResponse('I Form POST!!!')
				        
			'''针对CBV中的csrf_exempt只有方式3有效 针对其他装饰器上述三种方式都有效'''
			

在这里插入图片描述

四、Auth模块简介

		我们都知道在Django中有自带的一个接口 那就是Admin的接口 但是我们没有账号密码 那就体验不到管理员的强大功能了
		但是我们在做数据库迁移命令的时候发现有创建了10多张表格 其中有一张表格名字叫做Auth_user
		这个表格就是专门用来配合Auth模块做用户的注册、登录、修改密码、注销....等等很多功能 该表是Django admin后台管理默认的表
		Django 后台管理员账号创建需要到pycharm中的终端 
		python3 manage.py createsuperuser

在这里插入图片描述

五、Auth_user模块常见方法

		'''判断当前用户有没有登录操作'''
		html
		    <form method="post">
		        {% csrf_token %}
		        <p>username:<input type="text" name="username"></p>
		        <p>password:<input type="text" name="password"></p>
		        <input type="submit">
		    </form>
		    
		views
			def login(request):		
			    print(request.user)
			    '''
			        用户登录成功之后执行Auth.login 该方法返回当前登录用户对象  admin
			        用户没有登录成功没有执行Auth.login 该方法返回匿名用户对象  AnonymousUser
			    '''
			    print(request.user.is_authenticated)    # 判断当前用户是否登录 返回True False
			    if request.method == 'POST':
			        username = request.POST.get('username')
			        password = request.POST.get('password')
			        # 现在遇到一个问题就是怎么通过models.的方式去操作auth_user表格呢? 这个时候就有auth模块了
			        res = auth.authenticate(request, username=username, password=password)
			        # print(res.username, res.password,
			        #       res.pk)  # admin pbkdf2_sha256$150000$4NZp3wuIgf9A$7hfw7pcm35QosjTRWFpj9U3F5SoGTRqUv/H8DpBp308= 2
			        '''数据正确的情况下会有一个返回值是数据对象 数据错误的情况下返回的是None'''
			        if res:
			            auth.login(request, res)    # 自动操作Cookie与Session
			    return render(request, 'login.html')


		'''
		用户登录装饰器
		当用户没有登录的情况下跳转到注册界面 在settings文件中设置跳转的页面地址 LOGIN_URL = '/login/'
		'''
		
		from django.contrib.auth.decorators import login_required

		@login_required
		def index(request):
		    return HttpResponse('Form index view')
		
		@login_required
		def func(request):
		    return HttpResponse('Form func view')

		'''重置密码'''
		views
			@login_required
			def set_password(request):
			    if request.method == 'POST':
			        old_password = request.POST.get('old_password')
			        new_password = request.POST.get('new_password')
			        '''校验原密码是否正确 自定加密并检验'''
			        is_right = request.user.check_password(old_password)
			        if is_right:
			            request.user.set_password(new_password)  # 修改密码
			            request.user.save()  # 保存数据
			    return render(request, 'set_password.html')
		html
			<form action="" method="post">
			    {% csrf_token %}
			    <p>old_password:<input type="text" name=""></p>
			    <p>new_password:<input type="text" name=""></p>
			    <input type="submit">
			</form>
		
		'''自动清除Cookie与Session'''
		views
			@login_required
				def loginout(request):
				    auth.logout(request)  # 自动清楚cookie和Session
				    return HttpResponse('清除成功!!!')

		'''创建用户'''
		views
			from django.contrib.auth.models import User
			
			def register(request):
			    User.objects.create(username='Like', password=123, email='120@qq.com')	# 这里创建的是普通用户 不能登录管理员系统
			    return HttpResponse('注册成功!!!')

在这里插入图片描述

六、Auth_user表切换

		当我们使用管理员账户的时候发现字段不够管理员信息不够多 这个时候我们也没有办法添加字段
		所以就有了表切换的方法自定义一张表然后继承之前管理员表
		
		1.models
			from django.contrib.auth.models import AbstractUser
			'''主要是用来拓展Auth_user中没有的字段'''
			
			class Userinfo(AbstractUser):  # 继承原管理员表格
			    phone = models.BigIntegerField()	# 可以随意添加
			    desc = models.TextField()
			    
		2.settings.py
 			AUTH_USER_MODEL = 'app01.Userinfo'

七、基于django中间件设计项目功能

		'''简单的函数式封装 配置文件拔插式设计'''

		应用app.py
			class Dingding(object):
			    def __init__(self):
			        pass
			
			    def send(self, content):
			        print('DingDing消息通知', content)
			        
		settings
			NOTIFY_FUNC_LIST = [
			    'notifys.notify.qq.Qq',
			    'notifys.notify.wechat.Weixin',
			    'notifys.notify.dingding.Dingding',
			]
		__init__
			import importlib
			import settings
			
			def send_all(content):
			    for i in settings.NOTIFY_FUNC_LIST:
			        module_path, class_str_name = i.rsplit('.', maxsplit=1)
			        module = importlib.import_module(module_path)
			        class_name = getattr(module, class_str_name)
			        obj = class_name()
			        obj.send(content)	
		start
			from notifys import notify

			if __name__ == '__main__':
			    notify.send_all('国庆节要来啦!!!')
			    
		'''这个时候如果想让谁接收不到消息 注释掉即可 添加则是新建一个即可'''

在这里插入图片描述

技术小白记录学习过程,有错误或不解的地方请指出,如果这篇文章对你有所帮助请点点赞收藏+关注谢谢支持 !!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LoisMay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值