You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何拦截爬虫及Bot的不必要会话创建?(Asp.Net Webforms环境)

解决方案:ASP.NET WebForms中拦截特定Bot的会话创建

针对你遇到的「无Cookie爬虫/Bot生成大量无效会话」的问题,我整理了两种可行方案,优先推荐第一种无需修改SqlInMemoryProvider的方法,简单高效:


方案1:用Global.asax事件提前拦截(无需改动Provider)

在WebForms的请求流程里,会话创建是有固定触发时机的,咱们可以在会话初始化之前识别Bot请求,直接禁用当前请求的会话状态,从根源上阻止SqlInMemoryProvider创建会话。

具体操作步骤:

  1. 打开你的Global.asax文件,重写Application_PostAcquireRequestState事件——这个事件刚好在会话状态准备初始化前触发,是做判断的最佳时机。
  2. 编写Bot识别逻辑:可以结合「User-Agent特征」和「是否携带Cookie」两个条件(符合你说的“多数Bot不用Cookie”的场景)。
  3. 如果判定是目标Bot,调用SetSessionStateBehavior禁用当前请求的会话状态。

示例代码:

protected void Application_PostAcquireRequestState(object sender, EventArgs e)
{
    var context = HttpContext.Current;
    // 判断当前请求是否来自目标Bot
    if (IsTargetBot(context.Request))
    {
        // 禁用会话状态,直接阻止会话创建
        context.SetSessionStateBehavior(SessionStateBehavior.Disabled);
    }
}

// 自定义Bot识别逻辑,你可以根据实际需求调整规则
private bool IsTargetBot(HttpRequest request)
{
    // 先检查User-Agent是否包含常见爬虫标识
    var userAgent = request.UserAgent?.ToLower() ?? "";
    var isKnownBot = userAgent.Contains("googlebot") || userAgent.Contains("bingbot") || userAgent.Contains("slurp");
    
    // 再检查请求是否没有携带任何Cookie(对应你说的多数Bot不使用Cookie的情况)
    var noCookie = request.Cookies.Count == 0;

    // 满足任一条件即判定为Bot,你可以根据业务调整逻辑
    return isKnownBot || noCookie;
}

这个方案的好处是完全不用碰SqlInMemoryProvider,直接利用ASP.NET自带的请求生命周期机制实现拦截,兼容性好,测试起来也简单。


方案2:扩展SqlInMemoryProvider(方案1不生效时备选)

如果因为某些特殊场景(比如部分请求的会话状态初始化时机更早),方案1没能拦截成功,你可以尝试继承SqlInMemoryProvider,重写会话创建相关的方法,在创建会话前添加判断逻辑。

虽然这个Provider是非开源的,但它继承自标准的SessionStateStoreProviderBase,所以我们可以重写CreateNewStoreData方法——这个方法负责创建会话的存储数据,刚好可以在这里加Bot判断:

public class CustomSqlInMemoryProvider : SqlInMemoryProvider
{
    public override SessionStateStoreData CreateNewStoreData(HttpContext context, int timeout)
    {
        // 先判断是否是目标Bot
        if (IsTargetBot(context.Request))
        {
            // 如果是Bot,这里可以返回一个空的StoreData,或者直接触发禁用逻辑
            // 注意:不同Provider的内部实现可能有差异,建议先在测试环境验证
            return base.CreateNewStoreData(context, timeout);
        }
        else
        {
            // 正常用户请求,走原Provider的创建逻辑
            return base.CreateNewStoreData(context, timeout);
        }
    }

    // 复用方案1的Bot识别逻辑
    private bool IsTargetBot(HttpRequest request)
    {
        var userAgent = request.UserAgent?.ToLower() ?? "";
        var isKnownBot = userAgent.Contains("googlebot") || userAgent.Contains("bingbot") || userAgent.Contains("slurp");
        var noCookie = request.Cookies.Count == 0;
        return isKnownBot || noCookie;
    }
}

然后在web.config里把原来的Provider替换成你的自定义版本:

<sessionState mode="Custom" customProvider="CustomSqlInMemoryProvider">
  <providers>
    <add name="CustomSqlInMemoryProvider" type="你的命名空间.CustomSqlInMemoryProvider" connectionStringName="你的数据库连接字符串" />
  </providers>
</sessionState>

不过这个方案需要注意:因为SqlInMemoryProvider是非开源的,重写方法时可能会遇到内部实现的限制,一定要在测试环境充分验证后再上线。


小提示

  • 记得优化你的Bot识别逻辑,避免误拦截正常用户(比如有些用户可能也禁用了Cookie,你可以结合User-Agent和请求IP、访问频率等特征综合判断)。
  • 测试时可以用curl或者Postman模拟Bot请求:不带Cookie、设置Bot的User-Agent,验证会话是否被正确阻止创建。

内容的提问来源于stack exchange,提问作者MS Dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:42:37