web服务网关接口:
WSGI 是一种协议。
wsgiref 与uwsgi都是基于WSGI协议的一种web服务网关接口。
django中间件:
默认有七个中间键:
请求来的时候依次执行process_request方法
请求走的时候依次执行process——response方法
django中间件:全局访问频率限制,身份校验,黑名单、白名单
django中间键会依次从上往下走settings下的MIDDLEWARE中间件
如何自定义中间键:
在项目下新建一个文件夹(任意名)以下称为MyMiddleware,在MyMiddleware下新建一个mymiddleware.py
文件
在mymiddleware.py
文件下引入模块,并且定这样一个类:
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class MyMiddleWare(MiddlewareMixin):
def process_request(self,request):
print('im the first request')
def process_response(self,request,response):
print('im the first response')
return response
在settings的MIDDLEWARE下这样定义
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'Mymiddleware.mymiddleware.MyMiddleWare'
]
这样就完成了一个基本的中间件定义。
注:自定义中间件中带response形参的必须return repsonse,返回的是一个页面结果,如果不这样做的话,结果会丢失。
在process_request中直接return 数据(HttpResponse或Render,会直接走右边的process_response)
在process_view中return会走process_response的最下面一层,依次走完process_response
其他中间件:
process view 在路由匹配成功,视图启动之前。urls.py – views.py 之间执行。
process_exception 捕获views.py中视图函数的报错。
process_template 在视图函数views.py 渲染页面的时候会执行。
注:自定义中间件中带response形参的必须return repsonse,返回的是一个页面结果,如果不这样做的话,结果会丢失。
先写一个简单的post请求,复现报错信息
钓鱼网站:银行转账的路径,你是否也可以拿到,然后你做一个跟银行一模一样的页面,也超银行的借口提交数据,当用户在钓鱼网站输入对方账户名和转账金额之后,点击发送。其实内部是将对方账户换成了钓鱼网站的造假人员的账户。造成你转账转错账户的情况
开两个django项目,模拟转账的现象
如何区分钓鱼网站和正经网站?在正经网站返回页面的时候,在form表单中偷偷塞一个特殊的字符串,后端记下改页面对应的字符串的值,等用户发post请求来的时候,我先去校验特殊的字符串是否匹配
如何去写这个特殊的字符串呢?模版语法有一个固定的写法{% csrf_token %},必须写在form表单内
浏览器查看改标签的值,并且每次都在刷新。再来演示刚刚转账的示例
#引入csrf装饰器
from django.views.decorators.csrf import csrf_exempt,csrf_protect
@csrf_exempt
def home(reqeust):
return HttpResponse('ok')](https://img-blog.csdnimg.cn/20190423155317645.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2MDE5NDkw,size_16,color_FFFFFF,t_70)
网站没有启动csrf校验的情况下局部启用
views.py
@csrf_protect
def login(request):
return Httpresponse('login')
html下
1.form表单中:下面插入以下代码
{%csrf_token%}
2.ajax如何通过csrf校验
ajax提交:除了在form表单中插入{%csrf_token%}
外
还需在script脚本中插入以下ajax代码(注:script脚本写在最下方)
本段代码的重点是,我们在提交data数据的时候需要把csrfmiddlewaretoken
作为键,用jquery选择器找到csrfmiddlewaretoken
的值,作为data的一部分提交上去,这样就不会导致csrf引起的403forbidden.
urls.py 路由层(Myview是个类)
url('^index/',views.Myview.as_view())
先执行以下语句
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser #创建超级用户
views.py
from django.shortcuts import render,HttpResponse,redirect
from django.contrib import auth #用于存储登陆信息及对表的查询
from django.contrib.auth.models import User # 创建对应表的时候会用到
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = auth.authenticate(request,username=username,password=password) #查表,查到符合的返回user对象
if user : #如果user对象的返回结果有值,即从前端获取到了对象
auth.login(request,user) #相当于操作seesion记录,执行过后其他视图函数可以直接通过request.user获取当前用户对象。
return HttpResponse('登陆成功')
return render(request,'login.html')
def index(request):
print(request.user.is_authenticated) #判断是否处于登陆状态
print(request.user.username) #获取登录名
print(request.user.password) #获取登陆密码
return HttpResponse('index')
def logout(request):
auth.logout(request) #相当于request.session.flush()清空session中的键值
return HttpResponse('注销成功') #注销当前用户
#给函数加上一个“验证是否已经登陆”的装饰器【中间件中亦可处理】
from django.contrib.auth.decorators import login_required
#局部装饰器会自动校验你是否登陆,检验你的session信息,不需要其他
@login_required(login_url='/login/') #设定未登录状态时候的跳转页面
def home(request):
return HttpResponse('home')
#>>> http://127.0.0.1:8000/accounts/login/?next=/home/ #给出了一个错误跳转
#全局装饰器验证是否登陆进行跳转,在settings配置文件中进行配置,就不需要在局部配置了
#LOGIN_URL = '/login/'
def register(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
User.objects.create_user(username=username,password=password)
#User.objects.create_superuser(username=username,password=password) #创建超级用户,必须包含email字段,这里没有添加。
#User.objects.create(username=username,password=password) 密码不是密文的,在auth中不要使用此种方式创建用户
return render(request,'register.html')#创建表对象
#校验密码 修改密码
def set_password(request):
#jonathan666是原密码,jonathan777是新密码,这里偷懒没从前端获取数据
res = request.user.check_password('jonathan666')
if res:
request.user.set_password('jonathan888')
request.user.save()
return HttpResponse('ok')
图1:session_key对应网页中的session_id。session_data对应的就是user的数据
在默认的auth表中新建其他字段
from django.db import models
# Create your models here.
# 扩展auth_user表
# 方式一(不推荐):
# 一对一关联
# class UserDetail(models.Model):
# phone = models.CharField(max_length=11)
# user = models.OneToOneField(to=User)
# 方式二(推荐):
# 在setttings.py中设置
# AUTH_USER_MODEL = "app名.models对应的表名"
# 目的是告诉django不再使用默认的auth_user表,而使用我自己创建的Userinfo表
# AUTH_USER_MODEL = "app01.Userinfo"
from django.contrib.auth.models import AbstractUser
class Userinfo(AbstractUser): # 继承 AbstractUser表中的所有字段
avator = models.CharField(max_length=32)
# 注释:对数据的增删改查仍旧是用app01.model下的模型表,创建表的的方式create和create_user、create_superuser都可以使用,不同之处在于,create_user对密码字段进行了加密,create_superuser对密码字段进行了加密,并且创建超级用户那一栏为1。
原来数据库的其他操作:
-authentication
-login
-logout
-set_password
一样用,不一样的地方在于之前用到USER 表模型的地方都改成USERINFO
参考:https://www.cnblogs.com/liuqingzheng/articles/9628105.html
https://www.cnblogs.com/Dominic-Ji/p/9229509.html