AspNetCoreRateLimit应用于MVC项目求助

文章主要讨论如何在评论接口触发限流后,将用户重定向回文章页面并显示提示信息。作者使用了自定义中间件和MemoryCache来实现这一功能,当状态码为429时,将用户重定向至先前的页面并显示限流消息。此外,提到了AspNetCoreRateLimit组件,但未能直接利用其内置方法查询限流状态。
摘要由CSDN通过智能技术生成

就是我的需求是评论接口限流,然后触发限流后要回到文章页面告诉用户你触发了限流,但是,使用这个组件,他会将返回信息以页面的形式返回给你,我并不知道该如何去让他回到文章页面,也是琢磨了很久,用中间件去实现了这个效果,但是感觉不是很理想,如果有大佬知道更好的办法,可以私信或评论,感激不尽。

实现的效果图

评论接口

文章接口

_messages.Warning是博客开源作者封装的提示信息组件,可以采用别的方式去提示,问题不大。这里就是将从缓存中的提示信息提取出来,然后因为这里用的是缓存,用session做的唯一值处理,所以用session去取出来,如果从缓存中查出来存在,则提示被限流。

代码实现

原理就是把组件自带的信息提示设置为空字符串,自己在中间件中去使用。

这是限流规则:

这里参数就不做多的解释,可以去看之前发布的那篇文章。只要把Content设置为空字符串即可。

然后就开始去写中间件去处理触发了限流该怎么做

需要注册缓存服务

builder.Services.AddMemoryCache();

app.Use(async (context, next) =>
{
    var cache = context.RequestServices.GetRequiredService<IMemoryCache>();
    
    // 保存原始响应流
    var originalBody = context.Response.Body;
    
    // 创建一个新的响应流
    using var responseBody = new MemoryStream();
    context.Response.Body = responseBody;
    
    // 加载当前用户的 Session 对象
    await context.Session.LoadAsync();
    
    await next.Invoke();
    
    if (context.Response.StatusCode == 429)
    {
        var referer = context.Request.Headers["Referer"].ToString();
        
        // 从 Session 中获取一个字符串值
        var value = context.Session.GetString("key");
        if (string.IsNullOrEmpty(value))
        {
            // 如果 Session 中没有值,则设置一个字符串值
            context.Session.SetString("key", "value");
        }
        var sessionId = context.Session.Id;
        if (!cache.TryGetValue("Errors", out Dictionary<string, string> errors))
        {
            errors = new Dictionary<string, string>();
            cache.Set("Errors", errors, TimeSpan.FromSeconds(10));
        }
        
        errors[sessionId] = "您的请求已被限流,请稍后再试。";
        
        // 重置响应流位置
        responseBody.Seek(0, SeekOrigin.Begin);
        
        // 读取响应内容
        // var bodyText = new StreamReader(responseBody).ReadToEnd();
        
        // 设置新的响应流
        context.Response.Body = originalBody;
        
        // 设置新的响应状态码
        context.Response.StatusCode = 302;

        context.Response.Headers["Location"] = referer;
        
    }
    else
    {
        // 将响应流写回到原始响应流中
        responseBody.Seek(0, SeekOrigin.Begin);
        await responseBody.CopyToAsync(originalBody);
        
    }
});

注意这个中间件处理要放在app.UseRateLimit();前面。

结尾

AspNetCoreRateLimit原本就讲限流的ip存放在redis当中了的,但是我就是查不出来,如果能用该组件自带的方法查询出来,就不需要再写一个中间件,当429的时候再用缓存存一次会话了。

总之暂且先用这种办法吧,如果有更好的方法可以评论哟~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

野生的狒狒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值