Django新手:自定义DRF+SimpleJWT集成django-axes的问题
集成django-axes到自定义DRF登录视图的解决方案
问题1:实现登录锁定功能
由于你的登录视图是完全自定义的(未使用Django自带的authenticate()方法),django-axes无法自动捕获登录尝试事件,所以需要手动调用axes的工具函数来记录登录成功/失败行为,具体步骤如下:
配置axes识别自定义用户登录字段
你使用EmailId作为登录凭证,需要在settings.py中告知axes用这个字段来识别用户:AXES_USERNAME_FIELD = 'EmailId' # 匹配你的自定义用户模型的登录字段在登录视图中添加axes日志逻辑
修改你的login_view,在验证用户有效性前后分别处理锁定检查、失败记录和成功重置逻辑:from axes.utils import log_user_login_failure, log_user_login_success, is_user_locked @api_view(['POST']) @permission_classes([AllowAny]) @ensure_csrf_cookie def login_view(request): Account = get_user_model() EmailId = request.data.get('EmailId') password = request.data.get('password') response = Response() if (EmailId is None) or (password is None): raise exceptions.AuthenticationFailed('username and password required') user = Account.objects.filter(EmailId=EmailId).first() # 先检查用户是否已被axes锁定 if user and is_user_locked(user): raise exceptions.AuthenticationFailed('Account is locked due to too many failed login attempts. Please try again later.') if not check_user_validity(user, password): # 记录登录失败事件:存在用户则用用户实例,不存在则用提交的邮箱 log_user_login_failure(request, username=user.EmailId if user else EmailId) raise exceptions.AuthenticationFailed('The credentials are invalid') else: print('user is valid') # 记录登录成功,重置失败计数 log_user_login_success(request, user=user) tokenvals = get_jwt_tokens(user) response.set_cookie(key='refreshtoken', value=tokenvals['refresh_token'], httponly=True) response.set_cookie(key="accesstoken", value=tokenvals['access_token']) response.data = { 'access_token': tokenvals['access_token'], 'id': user.id } return response可选:自定义锁定规则
你可以在settings.py中调整axes的锁定参数,比如:AXES_FAILURE_LIMIT = 5 # 连续失败5次后锁定账户 AXES_COOLOFF_TIME = 1 # 锁定时长1小时(单位为小时) AXES_LOCK_OUT_BY_COMBINATION_USER_AND_IP = True # 按「用户+IP」组合锁定,提升安全性
问题2:是否需要保留django.contrib.auth.backends.ModelBackend?
这取决于你的自定义认证后端是否完全覆盖了ModelBackend的功能:
- 如果你的自定义后端已经实现了所有认证逻辑(包括验证用户密码、处理Django admin登录等场景),那么可以移除
ModelBackend,并将你的自定义后端加入AUTHENTICATION_BACKENDS列表,注意AxesBackend必须放在第一位:AUTHENTICATION_BACKENDS = [ 'axes.backends.AxesBackend', 'your_app_path.your_custom_backend.YourCustomAuthBackend', # 替换为你的自定义后端路径 ] - 如果项目中还有场景需要依赖
ModelBackend(比如默认的Django admin登录逻辑),则可以保留它,同时根据需求调整它和自定义后端的顺序(优先使用的后端放在前面)。
AxesBackend的核心作用是包装后续的认证后端,自动跟踪登录尝试行为,因此它必须是AUTHENTICATION_BACKENDS列表的第一个元素。
内容的提问来源于stack exchange,提问作者otaku_weeb
相关产品推荐
相关产品推荐

