带有中间件的登录认证

中间件版的登录验证需要依靠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",
]

 

posted on 2018-12-11 15:57  KD_131  阅读(847)  评论(0编辑  收藏  举报