asp.net core webapi 并发请求时 怎么保证实时获取的用户信息是此次请求的?

embedded/2025/1/11 17:58:54/

对于并发请求,每个请求会被分配到一个独立的线程或线程池工作线程上。通过 HttpContextAsyncLocal,每个线程都能独立地获取到它自己的上下文数据。由于这些数据是与当前请求相关的,因此在并发请求时不会互相干扰。

在并发请求时,确保每个请求能够实时获取与之相关的用户信息,主要依赖于以下方法:

  • HttpContext.User:ASP.NET Core 内置的请求上下文,保证每个请求独立获取用户信息。

  • AsyncLocal:用于在异步环境中传递请求相关的信息,确保跨线程和异步调用时的正确性。

  • AuthorizationFilterContext .HttpContext.Items:通过拦截器缓存用户信息,可以确保所有后续的请求处理都能正确访问用户信息。

  • 分布式缓存或会话存储:用于分布式应用场景,确保不同服务器上的请求能获取到正确的用户信息。

1. 使用 HTTP 请求上下文(如 HttpContext

在 ASP.NET Core 中,每个请求都是独立的,并且与当前线程绑定。当你发起一个请求时,ASP.NET Core 会将所有的请求上下文信息(包括认证、用户信息等)存储在 HttpContext 中。这意味着即使你有多个并发请求,每个请求的上下文都是独立的,可以保证每个请求都能获取到与该请求相关的用户信息。

获取用户信息:

你可以通过 HttpContext.User 来获取当前请求的用户信息:

public class MyController : ControllerBase
{public IActionResult Get(){var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;var username = User.Identity.Name;return Ok(new { userId, username });}
}

User 属性会在每个请求的上下文中自动填充,在每个请求线程中是独立的,因此不会发生并发请求时的混淆。

2. 使用 AsyncLocal 存储线程相关信息

在某些情况下,你可能需要跨多个方法、类或任务传递请求特定的信息(如用户信息)。AsyncLocal 提供了一种线程和任务绑定的方式,可以确保每个异步操作或线程都能获取到与当前请求相关的信息。

public class UserContext
{private static AsyncLocal<User> _currentUser = new AsyncLocal<User>();public static User CurrentUser{get => _currentUser.Value;set => _currentUser.Value = value;}
}

在每个请求的处理过程中,你可以将当前用户信息存储到 AsyncLocal 中,这样即使是异步操作,也能保证用户信息与当前请求相关。

使用方法:

在请求处理中,你可以在认证时设置用户信息:

public class MyController : ControllerBase
{public IActionResult Get(){// 假设从某处获取当前用户信息var user = new User { UserId = "123", Username = "JohnDoe" };UserContext.CurrentUser = user;return Ok(UserContext.CurrentUser);}
}

这种方法特别适用于需要跨多个异步方法传递用户信息的场景。

3. 使用拦截器IAuthorizationFilter注入用户信息

通过IAuthorizationFilter设置用户信息。这确保每个请求的用户信息都能被正确注入,尤其是在复杂的认证流程中。

 public class AuthorizationFilter : IAuthorizationFilter{public void OnAuthorization(AuthorizationFilterContext context){//var user = context.HttpContext.User;//if (user == null || !user.HasClaim("role", "Admin"))//{//    context.Result = new UnauthorizedResult();//}context.HttpContext.Items["AccountDetail"] = "Admin";}}

在请求处理中,你可以通过 HttpContext.Items 来获取用户信息:

public class MyController : ControllerBase
{public IActionResult Get(){var serviceProvider = HttpContext.RequestServices;var account = serviceProvider?.GetRequiredService<IHttpContextAccessor>().HttpContext?.Items["AccountDetail"];return Ok(account);}
}

注:需提前注入IHttpContextAccessor

      // 注册 IHttpContextAccessorbuilder.Services.AddHttpContextAccessor();

4. 使用分布式缓存或会话存储

在分布式应用中,可能无法依赖单一的线程或请求上下文来存储用户信息,这时可以使用分布式缓存(如 Redis)或会话存储来保存每个请求的用户信息。这确保了无论请求在哪个服务器或进程中被处理,用户信息始终能够正确获取。

使用会话存储:

ASP.NET Core 提供了内置的会话机制,可以在请求之间存储用户信息。

public class MyController : ControllerBase
{public IActionResult Get(){// 假设你已经将用户信息存入 Session 中var userId = HttpContext.Session.GetString("UserId");return Ok(new { userId });}
}

在中间件或认证过程中,可以设置用户信息到会话:

public class UserContextMiddleware
{private readonly RequestDelegate _next;public UserContextMiddleware(RequestDelegate next){_next = next;}public async Task InvokeAsync(HttpContext context){var user = new User { UserId = "123", Username = "JohnDoe" };context.Session.SetString("UserId", user.UserId);await _next(context);}
}


http://www.ppmy.cn/embedded/153077.html

相关文章

【JAVA面试】接口和抽象类

在四层架构&#xff08;Controller, Service, ServiceImpl, Mapper&#xff09;的设计中&#xff0c;接口和抽象类的选择对代码的可扩展性和设计模式的使用有很大影响。以下是接口&#xff08;interface&#xff09;和抽象类&#xff08;abstract class&#xff09;的区别&…

统计学习方法(第二版) 第五章 决策树

本章主要讨论决策树模型&#xff0c;以及生成、剪枝和分类的方法。 剪枝方法的补充 统计学习方法(第二版) 第五章 补充-CSDN博客 目录 基础数学知识&#xff1a; 1.自信息量 2.互信息 3.平均自信息量和熵 4.熵函数的性质 5.联合熵和条件熵 6.平均互信息量&#xff08;…

蓝桥杯嵌入式速通(1)

1.工程准备 创建一文件夹存放自己的代码&#xff0c;并在mdk中include上文件夹地址 把所有自身代码的头文件都放在headfile头文件中&#xff0c;之后只需要在新的文件中引用headfile即可 headfile中先提前可加入 #include "stdio.h" #include "string.h"…

在离线环境中安装 `.rpm` 包的步骤

在一些环境中&#xff0c;可能无法直接通过网络安装软件包。特别是在没有互联网连接的情况下&#xff0c;我们仍然可以手动下载 .rpm 安装包并进行离线安装。本文将介绍如何在离线环境中安装多个 .rpm 包&#xff0c;确保软件的顺利安装和依赖关系的处理。 1. 将 .rpm 文件复制…

sql 函数

# 四则运算 - * / # 函数 distinct 、count、sum、max、min、avg、sum、round select concat(device_id 是,device_id ) device_id from device_id_apply_factor where device_id D6A42CE6A0; select concat_ws(|||,device_id ,factor_a ,module_type) from 、device_id_app…

SSL 证书格式和证书文件扩展名:完整指南

SSL 证书是什么以及它如何工作相当容易理解。但当涉及到在服务器上安装它时&#xff0c;有时&#xff0c;你可能觉得这是在处理火箭科学。 由于有如此多的SSL 证书格式与特定服务器要求相关&#xff0c;您更有可能感到困惑和沮丧&#xff0c;而不是从一开始就正确配置证书。但…

热门力反馈手套对比,机器人遥操作完美解决方案

随着机器人技术的快速发展&#xff0c;遥操作机器人作为代替人类在危险环境中完成高危任务或在医疗领域完成远程精密手术的完美解决方案&#xff0c;正在快速进步&#xff0c;并有望成为拥有巨大潜力的机器人行业的全新发展方向。 本文将就推动机器人遥操作领域发展的力反馈手…

python初体验: 处理excel数据

一. data.xlsx 二.python代码 import pandas as pd# 读取 Excel 文件 df pd.read_excel(./data.xlsx, sheet_nameSheet1, usecols[Name, Age, City])# 查看数据 print(df.head())# 筛选数据 df_filtered df[df[Age] > 30]# 添加新列 df_filtered[Salary] df_filtered[Ag…