登录限制 锁定ip 限制访问


登录-限制ip

前情提要

用户使用手机号码登录 校验密码输入错误的次数
使用MySQL记录密码输入次数 当输入次数达到10次
使用redis记录ip地址 将限制该ip禁止访问页面 30min
本章使用: python3.6 django MySQL Redis

流程图

登录接口-->GET请求

参数 备注 请求方式
参考路由 http://127.0.0.1:8000/login/ 用户登录接口 GET
GET请求 login.html 返回登录页面

后端代码-->django/urls

from django.urls import re_path

# 新增一个路由
re_path(r'login/$', LoginView.as_view(), name="login"),  # 登录接口

后端代码-->django/views

class LoginView(View):

    def get(self, request):
        """返回登录页面"""
        ip_lock = get_ip_lock(request)  # get_ip_lock()自定义函数 用于获取ip是否被锁定限制
        if ip_lock:
            response = render(request, '404.html', ip_lock)
            return response
        return render(request, 'login.html')

后端代码-->django/utils

# 自定义工具包 用于获取ip
def get_ip_lock(request):
    """
    get lock ip
    :param request:
    :return:
    """
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    try:
        ip_lock_time = eval(redis_conn.get('ip_%s' % ip).decode())
        if ip_lock_time is not None:
            if (datetime.datetime.now() - ip_lock_time.get('time')).total_seconds() < 1800:
                s = int(1800 - (datetime.datetime.now() - ip_lock_time.get('time')).total_seconds())
                content = {'s_time': s}
                return content
    except Exception as e:
        pass

登录接口-->POST请求

参数 备注 请求方式
username/mobile kiki/13412345678 用户名/手机号 POST
password kiokiokiokio 密码

后端代码-->django/views

def post(self, request):
    username = str(request.POST.get('username')).strip()
    password = str(request.POST.get('password')).strip()
    remembered = request.POST.get('remembered')
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    if not all([username, password]):
       return render(request, 'login.html', {'account_errmsg': '缺少参数,请检查'})
    if not re.match(r'^[0-9a-zA-Z]{8,20}$', password):
       return render(request, 'login.html', {'account_errmsg': '密码长度8-20之间的英文与数字'})
    user = auth.authenticate(username=username, password=password)
    if user is None:
        try:
            user = User.objects.get(Q(username=username) | Q(email=username) | Q(mobile=username))
            get_lock_user(user, ip)  # 获取账号输入的密码错误次数记录与ip记录
            if user.pass_error >= 10:
                return render(request, 'login.html', {'account_errmsg': '密码错误超过10次,用户锁定半小时'})
            elif 5 <= user.pass_error <= 9:
                return render(request, 'login.html', {'account_errmsg': '密码错误超过5次,用户锁定十分钟'})
        except Exception as e:
            return render(request, 'login.html', {'account_errmsg': '暂无该账户,请先注册'})
        return render(request, 'login.html', {'account_errmsg': '账号或密码输入有误,请检查'})
    if user.is_login:
        return render(request, 'login.html', {'account_errmsg': '该账号已登录'})
    if 5 <= user.pass_error < 10:
        if (datetime.datetime.now() - user.login_lock).total_seconds() < 600:
            return render(request, 'login.html', {'account_errmsg': '账号锁定十分钟内不能登陆成功!'})
    login(request, user)
    if remembered != 'on':
        request.session.set_expiry(7 * 24 * 3600)
    else:
        request.session.set_expiry(7 * 24 * 3600)
    next = request.GET.get('next')
    if next:
        response = redirect(next)
    else:
        response = redirect(reverse('alex_index:index'))
    get_login_user(user)  # 用户登录成功 则将记录清除为0
    response.set_cookie('username', user.username, max_age=7 * 24 * 3600)
    return response

后端代码-->django/utils

def get_lock_user(user, ip):
    """
    get lock user
    :param user:
    :param ip:
    :return:
    """
    if user.ip is None or user.ip != ip:
        user.ip = ip
    user.login_lock = datetime.datetime.now()
    user.pass_error += 1
    if user.pass_error >= 10:  # if pass_error > 10 lockIP 当密码错误记录到10
        lock_ip_time = {"time": datetime.datetime.now(), 'ip': ip}  # 记录当前时间与ip
        redis_conn.setex('ip_%s' % ip, constants.IP_LOCK_TIME, str(lock_ip_time))  # redis记录ip
    user.save()

文章作者: 柒仔
文章链接: /article/14/
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 XiaoLiu!
侵权声明: 若无意对您的文章造成侵权,请您留言,博主看到后会及时处理,谢谢。
评论-----昵称和邮箱必填,网址选填
  目录