• 带有中间件的登录认证


    中间件版的登录验证需要依靠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",
    ]
  • 相关阅读:
    [No0000C9]神秘的掐指一算是什么?教教你也会
    [No0000C8]英特尔快速存储IRST要不要装
    [No0000C7]windows 10桌面切换快捷键,win10
    [No0000C6]Visual Studio 2017 函数头显示引用个数
    [No0000C4]TortoiseSVN配置外部对比工具
    [No0000C5]VS2010删除空行
    [No0000C3]StarUML2 全平台破解方法
    [No0000C2]WPF 数据绑定的调试
    [No0000C1]Excel 删除空白行和空白列VBA代码
    [No0000C0]百度网盘真实地址解析(不用下载百度网盘)20170301
  • 原文地址:https://www.cnblogs.com/kenD/p/10102743.html
Copyright © 2020-2023  润新知