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

ASP.NET Core中如何为匿名用户实现带声明令牌的身份识别?

ASP.NET Core 中半匿名用户的声明式身份识别方案

你完全可以利用ASP.NET Core的基于声明的认证系统(ASP.NET Core Identity底层依赖这套系统)来实现半匿名用户的持久化识别,不需要依赖显式登录流程,以下是成熟的落地方案:

核心思路

不启用ASP.NET Core Identity的用户注册/登录模块,直接使用Cookie认证中间件(或自定义Header传递)为匿名用户颁发包含NameIdentifier声明的身份凭证,让服务器能通过Context.User.Claims识别用户,同时通过Cookie或本地存储跨会话保留用户ID。


方案一:Cookie存储匿名ID(推荐,安全性更高)

1. 配置Cookie认证中间件

在Program.cs中注册Cookie认证服务,自定义认证Scheme和Cookie属性:

var builder = WebApplication.CreateBuilder(args);

// 注册Cookie认证,自定义Scheme名称
builder.Services.AddAuthentication("AnonymousAuth")
    .AddCookie("AnonymousAuth", options =>
    {
        options.Cookie.Name = "AnonymousUser";
        options.ExpireTimeSpan = TimeSpan.FromDays(365); // 长期保存用户ID
        options.SlidingExpiration = true; // 活动时自动延长有效期
        options.Cookie.HttpOnly = true; // 防止XSS窃取
        options.Cookie.SameSite = SameSiteMode.Lax;
        options.Cookie.SecurePolicy = CookieSecurePolicy.Always; // 仅HTTPS环境下发送
    });

// 添加SignalR服务
builder.Services.AddSignalR();

var app = builder.Build();

// 中间件顺序:路由 -> 认证 -> 自定义匿名用户处理 -> 授权 -> 端点
app.UseRouting();
app.UseAuthentication();

// 自定义中间件:生成/验证匿名用户ID
app.Use(async (context, next) =>
{
    // 仅处理未认证的请求
    if (!context.User.Identity.IsAuthenticated)
    {
        // 从Cookie读取已存在的匿名ID
        var anonymousId = context.Request.Cookies["AnonymousUser"];
        
        // 不存在则生成新的GUID
        if (string.IsNullOrEmpty(anonymousId))
        {
            anonymousId = Guid.NewGuid().ToString();
        }

        // 创建包含NameIdentifier声明的身份标识
        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.NameIdentifier, anonymousId)
        };
        var identity = new ClaimsIdentity(claims, "AnonymousAuth");
        var principal = new ClaimsPrincipal(identity);

        // 登录用户,将身份写入Cookie
        await context.SignInAsync("AnonymousAuth", principal, new AuthenticationProperties
        {
            IsPersistent = true,
            ExpiresUtc = DateTimeOffset.UtcNow.AddYears(1)
        });
    }

    await next();
});

app.UseAuthorization();

// 映射SignalR Hub
app.MapHub<GameHub>("/gameHub");

app.Run();

2. SignalR中获取用户ID

在Hub类中直接通过Context.User读取声明:

public class GameHub : Hub
{
    public async Task SendGameAction(string action)
    {
        // 获取匿名用户ID
        var userId = Context.User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
        
        // 执行业务逻辑,比如广播动作或保存游戏状态
        await Clients.Others.SendAsync("ReceiveGameAction", userId, action);
    }
}

方案二:本地存储(localStorage)+ Header传递

如果不想使用Cookie,可以让前端生成并存储匿名ID,通过请求Header传递给后端:

1. 前端代码(生成/存储ID)

// 初始化匿名用户ID
let anonymousId = localStorage.getItem('AnonymousUserId');
if (!anonymousId) {
    anonymousId = crypto.randomUUID();
    localStorage.setItem('AnonymousUserId', anonymousId);
}

// SignalR连接时添加Header
const connection = new signalR.HubConnectionBuilder()
    .withUrl("/gameHub", {
        headers: {
            "Anonymous-Id": anonymousId
        }
    })
    .build();

// 启动连接
connection.start().catch(err => console.error(err));

2. 后端中间件(读取Header并生成身份)

在Program.cs中添加自定义中间件,替代Cookie认证的登录逻辑:

app.Use(async (context, next) =>
{
    if (!context.User.Identity.IsAuthenticated)
    {
        // 从Header读取匿名ID
        var anonymousId = context.Request.Headers["Anonymous-Id"].FirstOrDefault();
        
        // 不存在则生成新ID并返回给前端
        if (string.IsNullOrEmpty(anonymousId))
        {
            anonymousId = Guid.NewGuid().ToString();
            context.Response.Headers.Add("Anonymous-Id", anonymousId);
        }

        // 创建身份标识
        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.NameIdentifier, anonymousId)
        };
        var identity = new ClaimsIdentity(claims, "AnonymousAuth");
        context.User = new ClaimsPrincipal(identity);
    }

    await next();
});

与ASP.NET Core Identity的兼容

如果后续需要支持用户注册升级(匿名用户转为正式注册用户),可以在Identity的ApplicationUser类中添加AnonymousId字段:

public class ApplicationUser : IdentityUser
{
    public string? AnonymousId { get; set; }
}

用户注册时,将当前的匿名ID关联到新用户,即可保留之前的游戏数据。


注意事项

  • 用户清除Cookie或localStorage会生成新ID,这是预期行为,无需额外处理。
  • 若使用Cookie方案,确保网站启用HTTPS,避免Cookie被窃取。
  • 不要在匿名用户的声明中包含敏感信息,仅用于身份识别。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 21:50:37