简介
钓鱼网站:假设是一个银行一摸一样的网址页面 用户 用户在该页面上转账
账户的钱会减少 但是受益人却不是自己想要转账的那个人
模拟
一台计算机上两个服务端不同端口启动 钓鱼网站地址改为正规网站的地址
钓鱼网站
style="display: none"
div class="container">
<div class="row">
<form action="https://127.0.0.1/8000/transfer/" method="post">
<p>用户名:<input type="text" name="user"></p>
<p>转入用户:<input type="text"></p>
<p><input type="text" name="target" value="kk" style="display: none"></p>
<p>转账金额<input type="text" name="price"></p>
<p><input type="submit" name="转账"></p>
</form>
</div>
</div>
预防
csrf
策略:通过在返回的页面上添加独一无二的标识信息从而区分正规网站和钓鱼网站的请求
<form action="" method=:"post">
{% csrf_token %}
</form>
方式一: 先编写csrf模板语法 然后利用标签查找和值获取 手动添加
{% csrf_token %}
# 利用属性选择器查找
data: {'username':'jason','csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]')}
方式二: 直接利用模板语法即可
data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'}
方式三: 通用方式(js脚本)
扩展性更高高
# 在配置文件中中 配置固定地址
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static')
]
#直接在html中引入
<script src="/static/csrf.js"></script>
创建js静态文件 导入
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 但是局部视图函数不许哟啊校验
需要先导入 模块 导入装饰器
from django.views.decorators.csrf import csrf_exempt,csrf_protect
校验csrf
csrf_protect
不校验csrf
csrf_exempt
@csrf_protect
def home(request):
return HttpResponse('hahaha')
针对CBV不能直接在方法上添加装饰器 需要借助于专门添加装饰器的方法
from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django import views
from django.utils.decorators import method_decorator
#方式二:直接在类上面添加 通过指名道姓装饰给类下的方法
@method_decorator(csrf_protect, name='post')
class MyHome(views.View):
#方式三:等于 类中所有方法添加 装饰器(且 csrf_exempt装饰器 只用该方式有效)
@method_decorator(csrf_protect)
def dispatch(self, request, *args, **kwargs):
return super(MyHome, self).dispatch(request,*args,**kwargs)
def get(self, request):
return HttpResponse('hahah')
@method_decorator(csrf_protect) #方式一:指名道姓 直接给类下的方法上添加
def post(self, request):
return HttpResponse('嘿嘿嘿')
注意:
针对csrf_exe,pt
只有方式三有效 针对其他装饰器上述三种方式都有效
django执行数据库迁移命令之后会产生一个auth_user表
该表可以配合auth模块坐用户相关的功能:注册、扽牢固、修改密码、注销····
该表还是django admin
后台管理默认的表
django admin
后台管理员账号创建
python manage.py createsuperuser
校验用户名是否正确
from django.contrib import auth
is_user_obj = auth.authenticate(request,username=username,password=password)
登录用户
auth.login(request,user_obj)
判断用户是否登录
print(request.user.is_authecticated) #返回布尔值
校验用户登录装饰器
@login_required(login_url='/login/')
from django.contrib.auth.decorators import login_required
#登录函数
def login(request):
from django.contrib import auth
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
is_user_obj = auth.authenticate(request, username=username, password=password)
if is_user_obj:
auth.login(request, is_user_obj) # 自动操作cookie和session
# print(is_user_obj.password)
# print(is_user_obj.pk)
# 跳转局部配置 跳转至登录 网页
@login_required(login_url='/login/')
def index(request):
return HttpResponse('index')
#跳转全局配置 在配置文件中 直接配置
LOGIN_URL = '/login/'
修改密码
校验旧密码是否正确
request.user.check_password(old_password)
修改密码
request.user.set_password(new_password)
request.user.save()
注销用户
auth.logout(request)
创建用户
create_user()
创建普通用户
create_superuser()
创建管理员用户 必须要添加邮箱字段
# 导入 该表的类
from django.contrib.auth.models import User
def reg(request):
User.objects.create_user(username='kk',password=123)
User.objects.create_superuser(username='ming',password='hong',email='888@163.com')
return HttpResponse('注册功能')
我们还想使用auth模块的方法并且扩展auth_user表字段
在models 给表坐扩展
from django.contrib.auth.models import AbstractUser
class Userinfo(AbstractUser):
"""扩展 auth_user表中没有的字段"""
# 创的时候 可以添加 参数使字段可以为空或 null=True
phone = models.BigIntegerField()
address = models.TextField()
还需要 在 配置文件中 修改配置
AUTH_USER_MODEL = 'app01.Userinfo'
首先 需要创建 一个包 将所有功能都分为py文件 存放在包下 还需创建配置文件 启动文件
在功能py文件中将功能封装为类 将功能使用 用相同的方法名 封装
class QQ(object):
def __init__(self):
pass
def send(self, content):
print(f'qq发送消息:{content}')
创建settings 配置文件
将包下的功能类 的调用路径全部以字符串形式 封装为一个列表
PACK_LIST = [
'packet.qq.QQ',
'packet.vx.VX',
'packet.tt.TT',
]
在启动文件中 调用包 就是调用包下的双下init 文件
所以主要 的逻辑 都双下init.py文件下 通过 调用importlib
模块 和settings
文件
import importlib
from django.utils.decorators import method_decorator
def re_by(func):
def inner(request):
import json
try:
request.data = json.loads(request.body)
res=func(request)
return res
except Exception:
request.data = request.POST
return func(request)
return inner
@method_decorator(re_by,name='post')
class BookView(View):
def get(self, request):
book_list = Book.objects.all()
# queryset 对象 不能直接序列化 只能通过 for循环 一个个拼成列表套字典
data_list = []
for book in book_list:
data_list.append({'name': book.name, 'price': book.price, 'publish': book.publish})
return JsonResponse(data_list, safe=False, json_dumps_params={'ensure_ascii': False})
def post(self, request):
res = request.data
print(res)
return HttpResponse('成功')