需求

  • 需求1: 如何使用 JS 判断用户是否处于活跃状态
- 参考网址: https://www.cnblogs.com/liuhangui/p/18196824/tracks-whether-the-user-is-being-inactive-in-js
- 通过监听各种事件来实现
    [
        'mousemove',    //鼠标移动
        'mousedown',    //鼠标按下
        'touchstart',   //触摸屏幕(移动端)
        'wheel',        //鼠标滚轮
        'resize',       //页面尺寸变化
        'keydown',      //键盘输入
    ]
  • 需求2: 用户登录错误次数限制

# 初始化错误尝试登录次数
login_attempts = 0
### users.serializers
class LoginSerializer(JSONWebTokenSerializer): # 继承原有的校验逻辑

    # 初始化错误尝试登录次数
    # login_attempts = 0
    def validate(self, attrs): # 在原先的 validate()方法基础上,优先校验验证码
        global login_attempts

        # 优先图形验证码校验
        image_code_id = self.initial_data.get('image_code_id',None)
        image_code = self.initial_data.get('image_code',None)
        if not image_code or not image_code:
            raise serializers.ValidationError('验证码不能空')
            # 如下处理方式行不通,正常响应了
            # return Response({'msg': '验证码不能为空', 'status_code': 1004}, status=status.HTTP_400_BAD_REQUEST)

        redis_conn = get_redis_connection('verify_codes')
        redis_byte_text = redis_conn.get(image_code_id)
        if not redis_byte_text:
            raise serializers.ValidationError('验证码不存在或已过期')
            # return Response({'msg': '验证码不存在或已过期', 'status_code': 1014}, status=status.HTTP_400_BAD_REQUEST)

        if image_code.lower() != redis_byte_text.decode('utf-8').lower():
            raise serializers.ValidationError('验证码错误')
            # return Response({'msg': '验证码错误', 'status_code': 1024}, status=status.HTTP_400_BAD_REQUEST)

		# 以下代码照抄源码即可
        credentials = {
            self.username_field: attrs.get(self.username_field),
            'password': attrs.get('password')
        }

        if all(credentials.values()):
            user = authenticate(**credentials)

            if user:
                if not user.is_active:
                    msg = _('User account is disabled.')
                    raise serializers.ValidationError(msg)

                payload = jwt_payload_handler(user)
                # 登录成功以后,清空登录错误次数
                login_attempts = 0
                return {
                    'token': jwt_encode_handler(payload),
                    'user': user
                }
            else:

                # 用户名 || 密码错误的逻辑丢这里
                login_attempts += 1
                print('登录尝试次数:',login_attempts)
                # conn = get_redis_connection('verify_codes')
                if login_attempts > 3:
                    if login_attempts == 4:
                        redis_conn.set('login_try_time',login_attempts,ex=180)
                        raise serializers.ValidationError('锁定登录{0}分钟,请{1}分钟后再尝试'.format(3,3),code=400)
                    else:
                        time_flag = redis_conn.get('login_try_time')
                        if time_flag:
                            print('还有{}秒后解锁'.format(redis_conn.ttl('login_try_time')))
                            raise serializers.ValidationError('锁定登录{0}分钟,请{1}分钟后再尝试'.format(3,3),code=400)
                        else:
                            login_attempts = 0
                msg = _('Unable to log in with provided credentials.')
                raise serializers.ValidationError(msg)
        else:
            msg = _('Must include "{username_field}" and "password".')
            msg = msg.format(username_field=self.username_field)
            raise serializers.ValidationError(msg)

  • JS就是数据
- 组件的构成,请求数据的格式,都是来源于'数据'