如果用户在 Django 中有 3 次或更少的失败登录尝试,则隐藏 reCatpcha 错误消息
Hide reCatpcha error message if user has 3 or less failed login attempts in Django
我是 Django 的初学者,有一个登录页面,当用户登录失败次数超过 3 次时,登录页面将显示 reCaptcha,效果很好。
但是,无论是否成功登录,我的登录页面仍然在每次登录尝试时显示无效验证码的错误消息(此错误消息来自 recaptcha 装饰器 - 'Invalid reCAPTCHA. Please try again.',尽管让我按我的方式登录已经编码)- 我想从我的登录页面隐藏这个特定的错误消息,除非用户有超过 3 次失败的登录尝试以及我如何在页面上显示实际的验证码。
我正在使用 django axes 检查失败的登录尝试,并禁用了不需要的用户锁定。
非常感谢对此的任何帮助。
网址
from django.urls import path, include
from django.contrib.auth import views as auth_views
from . import views
from .views import RequestPasswordResetEmail, CompletePasswordReset
#from .forms import EmailValidationOnForgotPassword
urlpatterns = [
path('login/', views.loginpage, name="login"),
path('logout/', views.logoutuser, name="logout"),
]
重新验证 decorator.py
from functools import wraps
from django.conf import settings
from django.contrib import messages
import requests
def check_recaptcha(view_func):
@wraps(view_func)
def _wrapped_view(request, *args, **kwargs):
request.recaptcha_is_valid = None
if request.method == 'POST':
recaptcha_response = request.POST.get('g-recaptcha-response')
data = {
'secret': settings.RECAPTCHA_PRIVATE_KEY,
'response': recaptcha_response
}
r = requests.post('https://www.google.com/recaptcha/api/siteverify', data=data)
result = r.json()
if result['success']:
request.recaptcha_is_valid = True
else:
request.recaptcha_is_valid = False
messages.error(request, 'Invalid reCAPTCHA. Please try again.')
return view_func(request, *args, **kwargs)
return _wrapped_view
查看
from django.conf import settings
from .decorators import check_recaptcha
from django.shortcuts import render, redirect
from django.contrib import messages, auth
from django.contrib.auth import authenticate, login, logout
from django.views import View
from .decorators import check_recaptcha
from axes.decorators import axes_dispatch
from axes.attempts import (
clean_expired_user_attempts,
get_user_attempts,
reset_user_attempts,
)
@axes_dispatch
@check_recaptcha
def loginpage(request, credentials: dict = None):
attempts_list = get_user_attempts(request, credentials)
attempt_count = max(
(
attempts.aggregate(Sum("failures_since_start"))[
"failures_since_start__sum"
]
or 0
)
for attempts in attempts_list
)
print(attempt_count)
attempt_count = attempt_count +1
context = {'attempt_count': attempt_count}
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
if user.is_active and attempt_count <= 3:
request.recaptcha_is_valid = True
login(request, user)
return redirect('home')
if user.is_active and attempt_count > 3 and request.recaptcha_is_valid:
login(request, user)
return redirect('home')
if not user.is_active:
messages.error(request, 'Account for this User has not been Activated.')
else:
messages.error(request, 'Username or Password is Incorrect.')
print(context)
return render(request, 'login.html', context)
模板登录
{% extends 'base.html' %}
{% block title %}User Login{% endblock %}
{% block content %}
<div class="d-flex justify-content-center">
<h3 id="form-title">Login</h3>
</div>
<div class="d-flex justify-content-center form_container">
<form method="POST" action="">
{% csrf_token %}
<div align="center">
<div class="input-group mb-2">
<div class="input-group-append">
<span class="input-group-text"><i class="fas fa-user"></i></span>
</div>
<input type="text" name="username" placeholder="Email" class="form-control">
</div>
<div class="input-group mb-3">
<div class="input-group-append">
<span class="input-group-text"><i class="fas fa-key"></i></span>
</div>
<input type="password" name="password" placeholder="Password" class="form-control">
</div>
</div>
{% include 'recaptcha.html' %}
<div class="d-flex justify-content-center mt-3 login_container">
<input class="btn login_btn" type="submit" value="Login">
</div>
</form>
</div>
{% for message in messages %}
<p>{{ message }}</p>
{% endfor %}
<div class="input-group mb-1">
</div>
<div class="mt-1">
<div class="d-flex justify-content-center links">
Don't have an account? <a href="{% url 'register' %}" class="ml-2">Sign Up</a>
</div>
<div class="d-flex justify-content-center links">
Forgot Password? <a href="{% url 'request-password' %}" class="ml-2">Reset Password</a>
</div>
</div>
{% endblock content %}
我设法通过将装饰器更新为仅在 4 次登录尝试失败后显示错误消息来解决此问题,如下所示:
重新验证 decorator.py
from django.conf import settings
from django.contrib import messages
from django.db.models import Sum
from functools import wraps
from axes.attempts import (
get_user_attempts,
)
import requests
def check_recaptcha(view_func, credentials: dict = None):
@wraps(view_func)
def _wrapped_view(request, *args, **kwargs):
attempts_list = get_user_attempts(request, credentials)
attempt_count = max(
(
attempts.aggregate(Sum("failures_since_start"))[
"failures_since_start__sum"
]
or 0
)
for attempts in attempts_list
)
print(attempt_count)
attempt_count = attempt_count + 1
request.recaptcha_is_valid = None
if request.method == 'POST':
recaptcha_response = request.POST.get('g-recaptcha-response')
data = {
'secret': settings.RECAPTCHA_PRIVATE_KEY,
'response': recaptcha_response
}
r = requests.post('https://www.google.com/recaptcha/api/siteverify', data=data)
result = r.json()
if result['success']:
request.recaptcha_is_valid = True
else:
request.recaptcha_is_valid = False
if attempt_count > 3+1:
messages.error(request, 'Invalid reCAPTCHA. Please try again.')
return view_func(request, *args, **kwargs)
return _wrapped_view
一切如我所愿!
我是 Django 的初学者,有一个登录页面,当用户登录失败次数超过 3 次时,登录页面将显示 reCaptcha,效果很好。
但是,无论是否成功登录,我的登录页面仍然在每次登录尝试时显示无效验证码的错误消息(此错误消息来自 recaptcha 装饰器 - 'Invalid reCAPTCHA. Please try again.',尽管让我按我的方式登录已经编码)- 我想从我的登录页面隐藏这个特定的错误消息,除非用户有超过 3 次失败的登录尝试以及我如何在页面上显示实际的验证码。
我正在使用 django axes 检查失败的登录尝试,并禁用了不需要的用户锁定。
非常感谢对此的任何帮助。
网址
from django.urls import path, include
from django.contrib.auth import views as auth_views
from . import views
from .views import RequestPasswordResetEmail, CompletePasswordReset
#from .forms import EmailValidationOnForgotPassword
urlpatterns = [
path('login/', views.loginpage, name="login"),
path('logout/', views.logoutuser, name="logout"),
]
重新验证 decorator.py
from functools import wraps
from django.conf import settings
from django.contrib import messages
import requests
def check_recaptcha(view_func):
@wraps(view_func)
def _wrapped_view(request, *args, **kwargs):
request.recaptcha_is_valid = None
if request.method == 'POST':
recaptcha_response = request.POST.get('g-recaptcha-response')
data = {
'secret': settings.RECAPTCHA_PRIVATE_KEY,
'response': recaptcha_response
}
r = requests.post('https://www.google.com/recaptcha/api/siteverify', data=data)
result = r.json()
if result['success']:
request.recaptcha_is_valid = True
else:
request.recaptcha_is_valid = False
messages.error(request, 'Invalid reCAPTCHA. Please try again.')
return view_func(request, *args, **kwargs)
return _wrapped_view
查看
from django.conf import settings
from .decorators import check_recaptcha
from django.shortcuts import render, redirect
from django.contrib import messages, auth
from django.contrib.auth import authenticate, login, logout
from django.views import View
from .decorators import check_recaptcha
from axes.decorators import axes_dispatch
from axes.attempts import (
clean_expired_user_attempts,
get_user_attempts,
reset_user_attempts,
)
@axes_dispatch
@check_recaptcha
def loginpage(request, credentials: dict = None):
attempts_list = get_user_attempts(request, credentials)
attempt_count = max(
(
attempts.aggregate(Sum("failures_since_start"))[
"failures_since_start__sum"
]
or 0
)
for attempts in attempts_list
)
print(attempt_count)
attempt_count = attempt_count +1
context = {'attempt_count': attempt_count}
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
if user.is_active and attempt_count <= 3:
request.recaptcha_is_valid = True
login(request, user)
return redirect('home')
if user.is_active and attempt_count > 3 and request.recaptcha_is_valid:
login(request, user)
return redirect('home')
if not user.is_active:
messages.error(request, 'Account for this User has not been Activated.')
else:
messages.error(request, 'Username or Password is Incorrect.')
print(context)
return render(request, 'login.html', context)
模板登录
{% extends 'base.html' %}
{% block title %}User Login{% endblock %}
{% block content %}
<div class="d-flex justify-content-center">
<h3 id="form-title">Login</h3>
</div>
<div class="d-flex justify-content-center form_container">
<form method="POST" action="">
{% csrf_token %}
<div align="center">
<div class="input-group mb-2">
<div class="input-group-append">
<span class="input-group-text"><i class="fas fa-user"></i></span>
</div>
<input type="text" name="username" placeholder="Email" class="form-control">
</div>
<div class="input-group mb-3">
<div class="input-group-append">
<span class="input-group-text"><i class="fas fa-key"></i></span>
</div>
<input type="password" name="password" placeholder="Password" class="form-control">
</div>
</div>
{% include 'recaptcha.html' %}
<div class="d-flex justify-content-center mt-3 login_container">
<input class="btn login_btn" type="submit" value="Login">
</div>
</form>
</div>
{% for message in messages %}
<p>{{ message }}</p>
{% endfor %}
<div class="input-group mb-1">
</div>
<div class="mt-1">
<div class="d-flex justify-content-center links">
Don't have an account? <a href="{% url 'register' %}" class="ml-2">Sign Up</a>
</div>
<div class="d-flex justify-content-center links">
Forgot Password? <a href="{% url 'request-password' %}" class="ml-2">Reset Password</a>
</div>
</div>
{% endblock content %}
我设法通过将装饰器更新为仅在 4 次登录尝试失败后显示错误消息来解决此问题,如下所示:
重新验证 decorator.py
from django.conf import settings
from django.contrib import messages
from django.db.models import Sum
from functools import wraps
from axes.attempts import (
get_user_attempts,
)
import requests
def check_recaptcha(view_func, credentials: dict = None):
@wraps(view_func)
def _wrapped_view(request, *args, **kwargs):
attempts_list = get_user_attempts(request, credentials)
attempt_count = max(
(
attempts.aggregate(Sum("failures_since_start"))[
"failures_since_start__sum"
]
or 0
)
for attempts in attempts_list
)
print(attempt_count)
attempt_count = attempt_count + 1
request.recaptcha_is_valid = None
if request.method == 'POST':
recaptcha_response = request.POST.get('g-recaptcha-response')
data = {
'secret': settings.RECAPTCHA_PRIVATE_KEY,
'response': recaptcha_response
}
r = requests.post('https://www.google.com/recaptcha/api/siteverify', data=data)
result = r.json()
if result['success']:
request.recaptcha_is_valid = True
else:
request.recaptcha_is_valid = False
if attempt_count > 3+1:
messages.error(request, 'Invalid reCAPTCHA. Please try again.')
return view_func(request, *args, **kwargs)
return _wrapped_view
一切如我所愿!