python API接口对ip做限制

本文详细介绍了三种不同的限频防刷策略:使用MySQL记录、使用Redis记录和使用Redis记录的升级版。每种策略都提供了具体的实现代码,包括如何限制同一IP在短时间内多次请求,以及如何限制每天的API调用次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这只是一个思路,具体的实现逻辑可以随意更改

①-使用mysql记录

1-modles

class Limit(models.Model):
    ip = models.CharField(max_length=20, verbose_name="ip地址")
    time = models.DateTimeField(verbose_name="创建时间")

    class Meta:
        db_table = "LimitFunction"

2-views 

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from models import Limit
from django.http import JsonResponse
import datetime, time, pytz


def iplimit(requests):
    ip_addr = requests.META.get("REMOTE_ADDR")
    try:
        ip_obj = Limit.objects.filter(ip=ip_addr)
        if ip_obj:
            # 改变格式(该格式和你配置文件中设置的格式一样),否则无法比较
            if (datetime.datetime.now().replace(tzinfo=pytz.timezone("Asia/Shanghai"))-ip_obj[0].time).total_seconds() <10:
                data = {
                    "code": "li-001",
                    "message": "10秒之内只能请求一次"
                }
                return JsonResponse(data)
            else:
                data = {
                    "code": "li-003",
                    "message": "该用户已新增"
                }
                return JsonResponse(data)
        else:
            limit = Limit.objects.create(ip=ip_addr, time=datetime.datetime.now().replace(tzinfo=pytz.timezone("Asia/Shanghai")))
            data = {
                "code": "li-000",
                "message": "新建用户成功",
                "ip": limit.ip,
                "time": limit.time
            }
            return JsonResponse(data)
    except:
        data = {
            "code": "li-002",
            "message": "查询用户异常"
        }
        return JsonResponse(data)

②-使用redis记录

def iplimit_redis(request):
    ip_addr = request.META.get("REMOTE_ADDR")
    try:
        redis_conn = get_redis_connection("default")
        ip_obj = redis_conn.get("ip_%s" % ip_addr)
        if ip_obj:
            data = {
                "code": "li-001",
                "message": "10秒之内只能请求一次"
            }
            return JsonResponse(data)
        else:
            try:
                redis_conn.setex("ip_%s" % ip_addr, 10, ip_addr)
                data = {
                    "code": "li-000",
                    "message": "新建用户成功",
                    "ip": ip_addr,
                }
            except:
                data = {
                    "code": "li-002",
                    "message": "新建异常"
                }
            return JsonResponse(data)
    except:
        data = {
            "code": "li-002",
            "message": "查询id异常"
        }
        return JsonResponse(data)

③-使用redis记录--升级版

def iplimit_redis_upper(request):
    ip_addr = request.META.get("REMOTE_ADDR")
    try:
        redis_conn = get_redis_connection("default")
        limit_flag = redis_conn.get("flag_%s" % ip_addr)
        if limit_flag:
            data = {
                "code": "li-001",
                "message": "24小时内不能再次访问"
            }
            return JsonResponse(data)
        else:
            try:
                redis_call_api_num = redis_conn.get("ip_%s" % ip_addr)
                if redis_call_api_num is None or int(redis_call_api_num) < 5:
                    if redis_call_api_num is None:
                        redis_conn.set("ip_%s" % ip_addr, 1)
                    else:
                        redis_conn.set("ip_%s" % ip_addr, int(redis_call_api_num) + 1)
                else:
                    redis_conn.setex("flag_%s" % ip_addr, 60*60*24, ip_addr)
                data = {
                    "code": "li-000",
                    "message": "数据更新成功",
                    "ip": ip_addr,
                }
            except:
                data = {
                    "code": "li-002",
                    "message": "数据更新异常"
                }
            return JsonResponse(data)
    except:
        data = {
            "code": "li-002",
            "message": "查询异常"
        }
        return JsonResponse(data)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值