中间件版的登录验证需要依靠session,所以数据库中要有django_session表。
先创建一个mysql的数据库
启动mysql服务器: net start mysql
以管理员身份登录: mysql -uroot -p
查看数据库: show databases;
创建数据库: create database db_middle
再去pycharm配置数据库
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': "db_middleware", "USER":"root", "PASSWORD":"", "HOST":"localhost", "PORT":"3306", } }
跟views在同一级的__init__里配置
import pymysql pymysql.install_as_MySQLdb()
url
from django.contrib import admin from django.urls import path from app01 import views urlpatterns = [ path('admin/', admin.site.urls), path("login/",views.login,name="login"), path("index/",views.index,name="index"), path("home/",views.home,name="home"), path("logout/",views.logout), ]
views
from django.shortcuts import render,HttpResponse,redirect # Create your views here. def index(request): return HttpResponse("this is index") def home(request): return render(request,"home.html") def login(request): if request.method == "POST": user=request.POST.get("user") pwd=request.POST.get("pwd") if user == "alex" and pwd == "123": request.session["user"]=user #设置session next_url=request.GET.get("next") #获取跳到登录页面之前的地址 #如果有,就跳转回登录之前的url if next_url: return redirect(next_url) else: return redirect("/index/") return render(request,"login.html") def logout(request): request.session.delete() # 删除服务器的session数据,不删除cookie return redirect("/login/")
templates
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登陆页面</title> </head> <body> <form action="{% url 'login' %}" method="POST"> {% csrf_token %} <p> <label for="user">用户名:</label> <input type="text" name="user" id="user"> </p> <p> <label for="pwd">密码:</label> <input type="password" name="pwd" id="pwd"> </p> <input type="submit" value="登录"> </form> </body> </html>
home.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>this is home</h3> <a href="/logout/">注销</a> </body> </html>
middlewares
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import redirect, HttpResponse class AuthMD(MiddlewareMixin): white_list=["/login/",] #白名单 black_list=["/black/",] #黑名单 def process_request(self,request): next_url = request.path_info print("path:",request.path) # 获取请求路径信息 print("path_info:",request.path_info) # 路径信息 不包含IP和端口、参数 print("get_full_path:",request.get_full_path()) # 路径信息 + 参数 #黑名单的网址爱限制访问 if next_url in self.black_list: return HttpResponse("this is an illegal url") #白名单的网址或者登陆用户不做限制 #访问的URL在白名单内或者session中有user用户名,则不做阻拦走正常流程 elif next_url in self.white_list or request.session.get("user"): return None else: return redirect("/login/?next={}".format(next_url))
再添加一个中间件 限制60秒之内最多尝试登录3次
# 限制60秒 之内最多只能访问3次 import time class Throttle(MiddlewareMixin): def process_request(self,request): # 获取访问记录 history = request.session.get("history",[]) # 获取当前时间 now = time.time() # history [ 9:16:30 , 9:16:35, 9:16:40 ] 9:26:50 # history [ 9:16:40 , 9:16:35, 9:16:30 ,] 9:26:50 while history and now - history[-1] > 60: #取出history列表中的最后一个 #如果超过一分钟 就pop删除最后一个 history.pop() if len(history) >= 3: return HttpResponse("你的访问频率太快了,你歇一会") history.insert(0,now) #把最新的时间数据插入到history的列表的最前端 request.session["history"]=history #把最近一次登录的记录添加到session
也可以根据ip做访问权限的限制, 效果同上
# 某些IP访问服务器的频率过高,进行拦截,比如限制 每 10 秒 不能超过 3次。 # 通过IP 也可以限制 import time visit_dict={} class Throttle(MiddlewareMixin): def process_request(self,request): #获取IP ip = request.META.get("REMOTE_ADDR") #获取访问记录 history = visit_dict.get(ip,[]) #没有访问记录 if not history: visit_dict[ip]=history #获取当前时间 now = time.time() # history [ 9:16:40 , 9:16:35, 9:16:30 ,] 9:26:50 # new = [] # for i in history: # if now - i > 10: # new.append(i) #把超过访问时间的记录放一个列表,之后循环删除 # # for i in new: # history.remove(i) #可以用下面的方法代替以上几行 while history and now - history[-1] > 10 : history.pop() if len(history)>=3: return HttpResponse("访问频率太快") history.insert(0,now)
settings
添加一条自定义中间件
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',
"app01.middlewares.middlewares.Throttle",
"app01.middlewares.middlewares.AuthMD",
]