首页 > 解决方案 > 限制用户登录尝试次数

问题描述

我正在使用瓶子的 @auth_basic 装饰器来构建我的登录模块。我想添加一个功能,如果用户输入错误的密码,他们将被限制重试 5 秒。这如何用瓶子的@auth_basic 来实现?

标签: pythonpython-3.xauthenticationbasic-authenticationbottle

解决方案


显然我没有实际的登录部分。但这是一种利用烧杯和装饰器来跟踪登录尝试的方法。

import gevent
from gevent import monkey, signal
monkey.patch_all()
from gevent.pywsgi import WSGIServer
from mainapp import mainappRoute
import bottle
from bottle import request, get, post, template
from beaker.middleware import SessionMiddleware
from whitenoise import WhiteNoise

staticfolder = 'static'
beakerconfig = {
    'session.type': 'memory',
    'session.auto': True,
    'session.cookie_path': '/',
    'session.key': 'site_id',
    'session.secret' : 'lsfkjsdlfhofuhrlifuheroifh',
    'session.httponly' : True
}

class user(object):
    def __init__(self):
        self.session = request.environ['beaker.session']
        self.login_attempts = 0

    def set(self, **kwargs):
        for k,v in kwargs.items():
            self.session[k] = v
        self.__dict__.update(self.session)

    def attempt(self):
        self.session['login_attempts'] = self.session.get('login_attempts', 0) + 1
        if self.session['login_attempts'] == 3:
            #do something like redirect
            pass


def check_login(fn):
    def check_uid(**kwargs):
        u = user()
        u.attempt()
        return fn(**kwargs)
    return check_uid

def shutdown():
    print('Shutting down ...')
    server.stop(timeout=60)
    exit(signal.SIGTERM)

@get('/login')
def login():
    return template('login.html')

@post('/login')
@check_login
def process_login():
    u = user()
    #let javascript handle the timeout
    return template('index.html', attempts=u.login_attempts)


botapp = bottle.app()
for Route in (mainappRoute,):
    botapp.merge(Route)
botapp = SessionMiddleware(botapp, beakerconfig)
botapp = WhiteNoise(botapp)
botapp.add_files(staticfolder, prefix='static/')
server = WSGIServer(("0.0.0.0", int(80)), botapp)
gevent.signal(signal.SIGTERM, shutdown)
gevent.signal(signal.SIGINT, shutdown)  # CTRL C
server.serve_forever()

推荐阅读