Day 65
今日内容概要
- csrf跨站请求伪造
- csrf操作方式
- csrf相关装饰器
- auth认证模块
- auth_user表切换
- 基于django中间件设计项目功能
今日内容详细
1.csrf跨站请求伪造
1.简介
钓鱼网站:假设是一个有一个和银行一样的网址页面,用户在该页面上转账 账户的钱会减少 但受益人不是要转账的人
2.模拟
一台计算机上两个服务端不同端口启动 钓鱼网站提交地址改为正规网站的地址(action=正规网站的地址)
3.预防预防
csrf策略:通过在返回的页面上添加独一无二的标识信息从而区分正规网站和钓鱼网站的请求
#真网站服务器针对真网站发送的请求会产生一个随机字符串发送给真网站。然后提交请求的时候需要先核对随机字符串是否一致,每次刷新的随机字符串都是不一样的。 而假网站并没有携带随机字符串,所以对真网站服务器提交的请求会失败
2.csrf操作方式
1.form表单
<form action="" method="post">
{% csrf_token %} #加一个模板语法即可
</form>
2.ajax
方式1:先编写csrf模板语法 然后利用标签查找和值获取 手动添加
'csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()
方式2:直接利用模板语法即可
'csrfmiddlewaretoken':'{{ csrf_token }}'
方式3:通用方式(js脚本)
扩展性最高
ajax方式三:
1.【settings.py】中配置静态文件资源:
最下方写入 STATICFILES_DIRS=[os.path.join(BASE_DIR,'static')]
2.新建一个文件夹static,再建一个csrf.js文件,里面加入下列代码
3.http文件中引入js文件 <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);
}
}
});
3.csrf相关装饰器
思考:
1.当整个网站默认都不校验csrf 但是局部视图函数需要校验 如何处理
2.当整个网站默认都校验csrf 但是局部视图函数不需要校验 如何处理
-----------------------------FBV------------------------------
from django.views.decorators.csrf import csrf_protect,csrf_exempt
"""
csrf_protect 校验csrf
csrf_exempt 不校验csrf
"""
# @csrf_protect
@csrf_exempt
def home(request):
return HttpResponse('哈哈哈')
-----------------------------CBV-----------------------------
针对CBV不能直接在方法上添加装饰器 需要借助于专门添加装饰器的方法
from django import views
from django.utils.decorators import method_decorator
class MyHome(views.View):
def get(self,request):
return HttpResponse('Home Get view')
@method_decorator(csrf_protect) #方式一:指名道姓的加
def post(self,request):
return HttpResponse('Home Post view')
————————————————————————————————————————————————————————
from django import views
from django.utils.decorators import method_decorator
@method_decorator(csrf_protect,name='post')#方式二 指名道姓的加
class MyHome(views.View):
def get(self,request):
return HttpResponse('Home Get view')
def post(self,request):
return HttpResponse('Home Post view')
————————————————————————————————————————————————————————
from django import views
from django.utils.decorators import method_decorator
class MyHome(views.View):
@method_decorator(csrf_protect)#方式三 影响类中所有方法
def dispatch(self, request, *args, **kwargs):
return super(MyHome, self).dispatch(request, *args, **kwargs)
def get(self,request):
return HttpResponse('Home Get view')
def post(self,request):
return HttpResponse('Home Post view')
#针对csrf_exempt只有方式三有效
#针对csrf_protect上述三种方式都有效
4.auth认证模块
django执行'数据库迁移命令'之后会产生一个auth_user表
该表可以配合auth模块做用户相关的功能:注册、登录、修改密码、注销...
该表还是django admin后台管理默认的表
'''
django admin后台管理员账号创建:
1. ctrl+alt+R>>:createsuperuser
2. 输入创建的管理员用户名、邮箱、密码、y。
3. 进入网页后缀为admin登录即可
全称为:python manage.py createsuperuser
'''
auth模块常见功能
1.创建注册用户
from django.contrib.auth.models import User
User.object.create_user(username,password)#创建普通用户
User.object.create_superuser(username,password,email)#创建管理员用户
'普通用户无法进入django中admin后台管理中'
'创建管理员用户中必须要给一个邮箱'
2.校验用户名和密码是否正确
from django.contrib import auth
user_obj=auth.authenticate(request,username,password)
#数据正确时返回的是数据对象
#数据错误时返回的时None
3.用户登录
auth.login(request,user_obj)
#自动操作cookie和session
4.判断用户是否登录
request.user.is_authenticated
5.获取登录用户对象
request.user
#当用户登录成功之后 该方法返回当前登录用户对象
#当用户没有登录成功 该方法返回匿名用户对象
6.校验用户登录装饰器
from django.contrib.auth.decorators import login_required
跳转局部配置
@login_required(login_url='/login/')
跳转全局配置
settings.py中写 LOGIN_URL = '/login/'
然后只用写 @login_required 即可
7.校验密码是否正确
is_right=request.user.check_password(old_password)
#返回值是布尔值
8.修改密码
request.user.set_password(new_passowrd)
request.user.save()#需保存数据!
9.注销登录
auth.logout(request)#自动清除cookie和session
5.auth_user表切换
#如还想使用auth模块的方法且扩展auth_user表的字段,则需要在models.py中自己写一张表
1.【models.py】中:
from django.contrib.auth.models import AbstractUser
class Userinfo(AbstractUser): #写一个类继承AbstractUser
'''扩展auth_user表中没有的字段'''
phone = models.BigIntegerField()
desc = models.TextField()
2.【settings.py】中:
AUTH_USER_MODEL = 'app01.Userinfo'#告诉django不要创auth_user,创Userinfo
3.执行数据库迁移命令后表中
#需注意如果之前已经做过数据库迁移命令,则只能切换一个新的库(mysql)
#1.命令创建一个Mysql库;然后settings.py中把库改为mysql,NAME、HOST、PORT、USER、PASSWORD、CHARSET;把原库链接删掉后执行数据库迁移;链接MySQL;即可发现没有auth_user表了变成了app01_Userinfo表(原字段+新扩展的字段) 且今后所有操作都会基于该表进行操作。
6.基于django中间件设计项目功能
"""
模块的导入有三种:
1. import 句式
2. from ... import ... 句式
3. 通过字符串形式导模块(django7个默认中间件)
"""
需了解:
eg:新建两个Py文件a和b,b在bbb文件夹内;在a.py中依靠字符串s1='bbb.b'找到b.py中的name对应的值
s1='bbb.b'
#print(s1.rsplit('.',maxsplit=1))#底层原理就是切割
import importlib#通过字符串导模块
res=importlib.import_module(s1)#等价于from bbb import b(res就是b模块) 最小只能到文件名,不能到里面的内容
print(res.name)
1.简单的函数式封装
def send_qq(content):
print('qq消息通知',content)
def send_vx(content):
print('vx消息通知',content)
def send_msg(content):
print('msg消息通知',content)
def send_all(content):
send_qq(content)
send_vx(content)
send_msg(content)
if __name__ == '__main__':
send_all('摩西摩西')#运行即可打印三条消息
2.配置文件插拔式设计(重要)需多看视频了解
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/289272.html