CSRF 跨站请求伪造 与 AUTH模块

CSRF 跨站请求伪造

最常见的跨站请求伪造有钓鱼网站,用于欺骗用户并获取用户的私密信息。“钓鱼网站”的页面与真实网站界面基本一致,诱骗消费者或者窃取访问者提交的账号和密码信息。钓鱼网站一般只有一个或几个页面,和真实网站差别细微 [1] 。钓鱼网站是互联网中最常碰到的一种诈骗方式,通常伪装成银行及电子商务、窃取用户提交的银行账号、密码等私密信息的网站,

原理简介

山寨一个页面,跟银行网站页面一模一样,诱骗用户来填写用户名、密码等信息,当用户在山寨页面上转账时,填写了对方账号,但会被悄悄替换成骗子的账户,然后再发送给银行处理,这样一来,用户本来想转给熟人的钱就被转给骗子了。

如何防范

只处理本网站页面发送的post请求。

识别当前请求是否是本网站发出的。

方法:

网站在返回给用户一个form表单的时候,会自动在该表单隐藏一个input框,这个框的value是一个随机字符串,但是网站能够记住每一个浏览器发送的随机字符串。

对于form表单,只需在表单中填写一个

如下示例:

<form action="" method="post">
	{% csrf_token %}
	<p>username:<input type="text" name="username"></p>
	<p>target_account:<input type="text" name="target_user"></p>
	<p>money:<input type="text" name="money"></p>
	<input type="submit">
	</form>
	<input type="hidden" name="csrfmiddlewaretoken" value="rJ47FeK9T55wavvVJGY6UxdM1kTMHhTqotGfaXjXIK8Ahz2Uvs02yR9T8bBn5q2D">

对于Ajax,防范方法有三种

方式1 任意的位置上书写{% csrf_token %}, 较为繁琐

​ 先在页面任意的位置上书写{% csrf_token %}
​ 然后在发送ajax请求的时候 通过标签查找获取随机字符串添加到data自定义对象即可

data:{'username':'jason','csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()},
方式2 较为简单
data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},		
方式3 官网提供的文件 最通用的一种方式

​ 直接兴建js文件拷贝代码 导入即可
​ 你不需要做任何的csrf相关的代码书

csrf相关的装饰器

from django.views.decorators.csrf import csrf_exempt,csrf_protect

# @csrf_exempt  # 不校验 csrf
def index(request):
	return HttpResponse('index')


@csrf_protect  # 校验
def login(request):
	return HttpResponse('login')

这两个装饰器作用在CBV上的区别:

# @method_decorator(csrf_exempt,name='post')  # csrf_exempt不支持该方法
@method_decorator(csrf_exempt,name='dispatch')  # csrf_exempt
class MyIndex(views.View):
	# @method_decorator(csrf_exempt)  # 可以
	def dispatch(self, request, *args, **kwargs):
		return super().dispatch(request,*args,**kwargs)
	def get(self,request):
		return render(request,'transfer.html')
	# @method_decorator(csrf_exempt,name='post')  # csrf_exempt不支持该方法
	def post(self,request):
		return HttpResponse('OK')	
    
	# csrf_exempt这个装饰器只能给dispatch装才能生效
    # csrf_protect方式全都可以  跟普通的装饰器装饰CBV一致
    
# @method_decorator(csrf_protect,name='post')  # 可以
class MyIndex(views.View):
	@method_decorator(csrf_protect)
	def dispatch(self, request, *args, **kwargs):
		return super().dispatch(request,*args,**kwargs)
	def get(self,request):
		return render(request,'transfer.html')
	# @method_decorator(csrf_protect)  # 可以
	def post(self,request):
		return HttpResponse('OK')

django settings源码剖析

django有两个配置文件

​ 一个是暴露给用户可以配置的,即项目文件夹中的settings.py文件
​ 一个是内部全局的(用户配置了就用用户的 用户没有配就用自己的),用此语句导入

from django.conf import settings
from django.conf import global_settings

然后CTRL + 鼠标左键点击settings,看对应源码,

分析源码可知:django是先加载全局配置 给对象设置
然后在加载局部配置 再给对象设置。局部配置里边有就用局部的,局部没有就用全局的。

auth 模块

Auth模块是Django自带的用户认证模块。用于实现包括用户注册、用户登录、用户认证、注销、修改密码等功能。

auth模块常用方法:

1、创建用户

from django.contrib.auth.models import User
# User.objects.create(username=username,password=password)  # 不可用,密码不是加密的
# User.objects.create_user(username=username,password=password)  # 创建普通用户,密码自动加密
# User.objects.create_superuser(username=username,password=password,email='123@qq.com')  # 创建超级用户,需要邮箱数据

2、校验用户名和密码是否正确

from django.contrib import auth
user_obj = auth.authenticate(request,username=username,password=password)
# 必须传用户名和密码两个参数缺一不能

3、保存用户登录状态

auth.login(request,user_obj)
# 只要这句话执行了 后面在任意位置 只要你能拿到request你就可以通过request.user获取到当前登录的用户对象

4、判断当前用户是否登录

request.user.is_authenticated()

5、校验原密码是否正确

request.user.check_password(old_password)

6、修改密码

request.user.set_password(new_password)
request.user.save()  # 千万记住

7、注销

auth.logout(request)

8、校验用户是否登录装饰器

from django.contrib.auth.decorators import login_required

局部配置
	@login_required(login_url='/login/')
	def index(request):
		pass
全局配置
	settings配置文件中 直接配置
	LOGIN_URL = '/login/'
	@login_required
	def index(request):
		pass
# 如果全局配置了 局部也配置  以局部的为准

扩展auth_user表字段

方法一:利用一对一外键字段关系

class UserDetail(models.Model):
	phone = models.BigIntegerField()
	user = models.OneToOneField(to='User')

方法二:利用继承关系

from django.contrib.auth.models import AbstractUser
class Userinfo(AbstractUser):
phone = models.BigIntegerField()
register_time = models.DateField(auto_now_add=True)
			
# 一定要注意 还需要去配置文件中配置
AUTH_USER_MODEL = 'app01.Userinfo'  # 应用名.表名
# 这么写完之后 之前所有的auth模块功能全都以你写的表为准 
posted @ 2019-12-05 21:44  AllenCH  阅读(429)  评论(0编辑  收藏  举报