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

ASP.NET Webforms下实现页面仅可通过站内跳转访问且链接单次有效

ASP.NET WebForms 单次有效链接实现方案(.NET 4.0 兼容)

核心逻辑是为每个站内跳转链接生成唯一的一次性校验Token,Token存储在当前用户的服务端Session中,请求页面时校验Token有效性,校验通过立即销毁该Token,实现单次使用限制。

1. 实现Token管理公共类

创建通用类处理Token的生成、存储和校验逻辑:

using System;
using System.Collections.Generic;
using System.Web;

public static class UrlTokenManager
{
    // 存储有效Token的Session键名
    private const string ValidTokenSessionKey = "OneTimeAccessTokens";

    /// <summary>
    /// 生成新的一次性访问Token
    /// </summary>
    public static string GenerateToken()
    {
        string newToken = Guid.NewGuid().ToString("N");
        HashSet<string> validTokens = HttpContext.Current.Session[ValidTokenSessionKey] as HashSet<string> 
            ?? new HashSet<string>();
        validTokens.Add(newToken);
        HttpContext.Current.Session[ValidTokenSessionKey] = validTokens;
        return newToken;
    }

    /// <summary>
    /// 校验Token有效性,校验通过立即销毁该Token
    /// </summary>
    public static bool ValidateAndConsumeToken(string token)
    {
        if (string.IsNullOrWhiteSpace(token))
            return false;

        HashSet<string> validTokens = HttpContext.Current.Session[ValidTokenSessionKey] as HashSet<string>;
        if (validTokens == null || !validTokens.Contains(token))
            return false;

        // 移除已使用的Token,实现单次生效
        validTokens.Remove(token);
        HttpContext.Current.Session[ValidTokenSessionKey] = validTokens;
        return true;
    }
}

2. 所有站内跳转链接拼接Token

生成跳转链接时统一追加一次性Token参数:

后台代码生成链接示例

// 生成商品详情页跳转链接
int productId = 1001;
string detailUrl = string.Format("ProductDetail.aspx?id={0}&ot_token={1}", 
    productId, UrlTokenManager.GenerateToken());
// 赋值给HyperLink控件
hlProduct.NavigateUrl = detailUrl;

前台aspx页面直接生成链接示例

<!-- 服务器控件写法 -->
<asp:HyperLink ID="hlAbout" runat="server" 
    NavigateUrl='<%# "About.aspx?ot_token=" + UrlTokenManager.GenerateToken() %>' 
    Text="关于页面">
</asp:HyperLink>

<!-- 原生a标签写法 -->
<a href="Contact.aspx?ot_token=<%= UrlTokenManager.GenerateToken() %>">联系页面</a>

3. 全局请求校验

在Global.asax的Application_BeginRequest事件中添加全局校验逻辑,无需每个页面单独处理:

protected void Application_BeginRequest(object sender, EventArgs e)
{
    string requestPath = Request.Url.AbsolutePath.ToLower();
    // 仅校验aspx页面请求,跳过静态资源(css、js、图片等)
    if (!requestPath.EndsWith(".aspx"))
        return;

    // 跳过不需要校验的入口页面,比如首页、登录页等用户可直接访问的页面
    if (requestPath == "/default.aspx" || requestPath == "/login.aspx")
        return;

    // 获取请求携带的Token
    string accessToken = Request.QueryString["ot_token"];
    // 校验失败直接重定向到错误页
    if (!UrlTokenManager.ValidateAndConsumeToken(accessToken))
    {
        Response.Redirect("/AccessError.aspx", true);
    }
}

适配说明

  • 表单提交后跳转的目标URL,也需要追加新生成的Token参数
  • Token随Session生命周期生效,默认20分钟无操作后失效,可根据需求调整Session超时时间
  • 该方案默认不兼容浏览器回退后重复点击同一链接的场景,若需要兼容可调整校验逻辑不销毁Token,配合Request.UrlReferrer校验即可,但Referer存在伪造风险,安全性低于一次性Token方案

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 00:24:03