钓鱼网站利用的就是csrf
通过开发一个和正规网站一模一样的页面,当用户不经意点击进去后,用户以为这就是正规的网站(因为长得都一样)。此时用户可能会在这个虚假的网页上做一些操作,最后往后端提交数据时,虚假网站其实对用户提交的数据做一定的篡改,再往正规网站后端提交。
request.POST
中的随机字符串是否和网站之前保存的随机字符串相同基于该项目是django项目
{% csrf_token %}
即可<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>
先在页面任意的位置上书写{% csrf_token %}
然后在发送ajax请求的时候 通过标签查找获取随机字符串添加到data自定义对象即可
data:{'username':'jason','csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()},
data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},
直接新建js文件拷贝官方代码,再在html文件中导入即可
你不需要做任何的csrf相关的代码书写
<!--这里直接提供了官方的代码,直接拷贝即可-->
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_protect
csrf_exempt
csrf_protect
装饰器# 应用文件夹的views文件中
from django.views.decorators.csrf import csrf_protect
@csrf_protect # 直接装饰在视图函数上
def index(request):
return HttpResponse('index')
# 应用文件夹的views文件中
from django.views.decorators.csrf import csrf_protect
from django.views import View
from django.utils.decorators import method_decorator
@method_decorator(csrf_protect,name='post') # 1. 可以
class MyIndex(views.View):
# @method_decorator(csrf_protect) # 2. 可以
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) # 3. 可以
def post(self,request):
return HttpResponse('OK')
csrf_exempt
装饰器# 应用文件夹的views文件中
from django.views.decorators.csrf import csrf_protect
@csrf_exempt # 直接装饰在视图函数上
def index(request):
return HttpResponse('index')
dispatch
方法装才有效from django.views.decorators.csrf import csrf_protect
from django.views import View
from django.utils.decorators import method_decorator
# @method_decorator(csrf_exempt,name='post') # 1. csrf_exempt不支持该方法
@method_decorator(csrf_exempt,name='dispatch') # 2. 可以
class MyIndex(views.View):
# @method_decorator(csrf_exempt) # 2. 可以
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') # 3. csrf_exempt不支持该方法
def post(self,request):
return HttpResponse('OK')
# 新建两个conf文件夹,conf1中新建一个settings.py文件,conf2中新建一个global_settings.py文件,且conf2文件夹中含有__init__.py文件。settings.py当做暴露给用户的 ,global_settings.py当做全局的
# 与conf1,conf2同一级中,新建一个启动文件start.py
# dir(obj) 作用是列出obj中所有的名字,保存成列表
# settings.py文件中
NAME = '我是暴露给用户的自定义配置'
# global_settings.py文件中
NAME = '我是项目默认的配置文件'
# conf2文件夹中的__init__.py文件中
import importlib
from conf2 import global_settings
import os
class Settings(object):
def __init__(self):
# 先将全局中的global_settings.py文件中的配置内容加载进来
for name in dir(global_settings):
if name.isupper():
setattr(self,name,getattr(global_settings,name))
# 获取暴露给用户的配置文件字符串路径
module_path = os.environ.get('xxx')
md = importlib.import_module(module_path) # md = settings
# 再将局部中的settings文件中的配置内容加载进来,有和全局配置相同的就覆盖掉全局的
for name in dir(md):
if name.isupper():
k = name
v = getattr(md,name)
setattr(self,k,v)
settings = Settings()
# start.py文件中
import os
import sys
BASE_DIR = os.path.dirname(__file__)
sys.path.append(BASE_DIR) # pycharm会自动将根目录添加到环境变量,但是其他开发环境可能没有这个功能,所以为了更加安全完善。这里要写这样一句话,把根目录添加到环境变量
if __name__ == '__main__':
# os.environ.setdefault('xxx','conf1.settings') # 等价于下一行
os.environ['xxx'] = 'conf1.settings' # environ 就是一个大字典
from conf2 import settings
print(settings.NAME)
auth
模块auth
模块的时候,要用就用全套(即不要一会用普通的方法来操作表,一会又用auth模块的方法来操作。类似面向对象中,子类重用父类的方法时,super().__init__(要重用的属性)
和父类.__init__(self,要重用的属性)
这两个也不能混用)python manage.py createsuperuser
auth
模块常用方法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='nick',password='123',email='123@qq.com') # 创建超级用户 必须要有邮箱数据
from django.contrib import auth
user_obj = auth.authenticate(request,username=username,password=password) # 必须传用户名和密码两个参数,缺一不可
request.user
中。from django.contrib import auth
auth.login(request,user_obj) # 只要这句话执行了,后面在任意位置,只要你能拿到request你就可以通过request.user获取到当前登录的用户对象
request.user.is_authenticated()
request.user.check_password(old_password)
request.user.set_password(new_password)
request.user.save() # 千万不要忘了
from django.contrib import auth
auth.logout(request)
# 1. 局部配置
# views文件中:
from django.contrib.auth.decorators import login_required
@login_required(login_url='/login/')
def index(request):
pass
# 2. 全局配置:需要在settings文件中配置一些数据
# settings配置文件中 直接配置
LOGIN_URL = '/login/'
# views文件中:
from django.contrib.auth.decorators import login_required
@login_required
def index(request):
pass
# 如果全局配置了 局部也配置 以局部的为准
auth_user
表字段有两种方式
利用一对一外键字段,再创建一张表保存新的字段
利用继承关系,重写auth_user
表
class UserDetail(models.Model):
phone = models.BigIntegerField()
user = models.OneToOneField(to='User')
AUTH_USER_MODEL = ‘app01.Userinfo‘ # 应用名.表名
,这么写完之后,你新建的Userinfo
表会代替原来的auth_user
表,之前所有的auth
模块功能全都以你写的表为准)from django.contrib.auth.models import AbstractUser
class Userinfo(AbstractUser):
phone = models.BigIntegerField() # 新增字段phone
register_time = models.DateField(auto_now_add=True) # 新增字段register_time
跨站请求伪造(csrf),django的settings源码剖析,django的auth模块
原文:https://www.cnblogs.com/Mcoming/p/11992149.html