如何创建和访问 Session .net core api?

Posted

技术标签:

【中文标题】如何创建和访问 Session .net core api?【英文标题】:How to Create and Access Session .net core api? 【发布时间】:2019-07-18 23:24:24 【问题描述】:

我需要在 api 中创建和访问会话。例如,我有一个名为 Login,Profile 的 api。当当时调用登录 api 时,我需要创建会话,并且我需要访问配置文件 api 中的会话。清除会话后,登录和配置文件 api 不允许用户访问。怎么做。

谢谢你..

【问题讨论】:

API 是无状态的。他们没有会话。 感谢您的回复@Chris Pratt。是否还有其他可能维持会话 没有。没有要维护的会话。每个请求都是唯一的,您必须将服务请求所需的所有数据与请求一起传递(通过请求正文和/或请求标头)。目前尚不清楚您最终要达到什么目标,因此无法为您提供更多帮助。 @ChrisPratt 我们如何在 api 用户之间存储小信息?如果 web api 中不存在会话? API 不是这样工作的。客户端负责传回服务器所需的所有信息。服务器只是通过响应发送客户端需要的信息。然后,这将成为您记录的 API 的一部分,即服务器在响应正文中返回 X,作为客户端,您需要将 X 作为请求的一部分发回。 【参考方案1】:

其实 .net core 可以很方便的访问 session。会话机制是 aspnet 中的一个基本特性(.netcore 也是) https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state?view=aspnetcore-2.2

我想你只需要添加

    services.AddDistributedMemoryCache();

    services.AddSession(options =>
    
        // Set a short timeout for easy testing.
        options.IdleTimeout = TimeSpan.FromSeconds(10);
        options.Cookie.HttpOnly = true;
    );

ConfigureServices 和:

app.UseSession();

Configure

然后你可以通过在你需要的地方注入ISession来在任何地方使用它。由于这是按设计分发的,因此您应该使用 JsonConvert.SerializeObject 之类的方式序列化您的数据,然后将它们反序列化。

此处描述的此功能与安全概念无关。

【讨论】:

【参考方案2】:

在 Startup.cs 中,您可以通过添加此行来添加 cookie 身份验证(您还可以指定会话长度等选项)。

services.AddAuthentication().AddCookie();

要在登录时创建会话,从控制器中,您可以调用它以具有一组声明(基本上是描述您需要了解的用户信息的键/值对)的用户身份登录:

await HttpContext.SignInAsync(userId, claims);

这将创建一个 ClaimsPrincipal 可以通过 Controller 上的 User 属性访问:

User.HasClaim("someclaim", "somevalue")

最终中间件会加密声明并将它们保存到 cookie,因此从服务器的角度来看,身份验证仍然是无状态的。请注意,默认情况下它使用的加密密钥与机器相关联,因此如果您计划扩展到多个服务器实例,则必须使用 azure or redis 之类的东西。

如果你想拥有一个完整的登录和用户管理系统,最简单的方法可能是 ASP.net 身份,它提供了用于处理用户、策略、访问组和一些棘手的东西,例如使用密码存储实体框架。有关这方面的更多信息,请查看:https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-2.2&tabs=visual-studio


附带说明,对于更通用的会话状态,this document 包含有关其他会话状态选项的数据,但由于您询问了登录,因此最好的选择可能是使用身份验证 API。

【讨论】:

这是否也适用于 API 基础项目【参考方案3】:

好的,你需要做两件事。在 startup.cs 中:

1- 将 app.UseSession(); 添加到 Configure 方法中。

2- 要对 cookie 进行更多控制,请在 ConfigureServices 方法中插入以下代码:

options.IdleTimeout = TimeSpan.FromSeconds(10);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;

如果它解决了问题就喜欢这个。

【讨论】:

【参考方案4】:

在 ASP.NET Core 5 - WebAPI 中,

    创建一个 UserLoginSessionMiddleWare 类。
    public class UserLoginSessionHandlerMiddleware
    
        private readonly RequestDelegate _next;
        public UserLoginSessionHandlerMiddleware(RequestDelegate next)
        
            _next = next;
        
        public async Task Invoke(HttpContext httpContext, IJwtAuthentication jwtAuthentication)
        
            var token = httpContext.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
            var userType = jwtAuthentication.ValidateToken(token);
            if (userType != null)
            
                httpContext.Items["CurrentUser"] = userType;
            
            await _next(httpContext);
        
    
    在 Invoke() 方法中,访问 Microsoft.AspNetCore.Http.HttpContext 对象作为参数。 创建并分配需要存储在会话中的 myObject,例如, httpContext.Items["SessionObject"] = myObject; 在 Startup.cs -> Configure() 方法中添加 UserLoginSessionHandlerMiddleware 以请求管道。 app.UseMiddleware<UserLoginSessionHandlerMiddleware>(); 从您的 ApiController 类访问 httpContext.Items["SessionObject"]

【讨论】:

【参考方案5】:

首先安装 nuget 包 - Microsoft.AspNetCore.Session

在 Startup.cs 文件中

public void ConfigureServices(IServiceCollection services)

    .....
    services.AddSession(options => 
        options.IdleTimeout = TimeSpan.FromMinutes(20);//You can set Time  
        options.Cookie.HttpOnly = true;
        options.Cookie.IsEssential = true;
        );
    .....


public void Configure(IApplicationBuilder app)

    ....
    app.UseSession();
    ....

在 HomeController 文件中

using Microsoft.AspNetCore.Http;

public class HomeController : Controller
    
    public ActionResult Index()
       
      HttpContext.Session.SetString("key", "value"); // Set Session  
      var x = HttpContext.Session.GetString("key"); // Get Value of Session
        

您也可以在会话中设置整数值,使用 SetInt32 方法和从 GetInt32 方法获取。希望对你有帮助。。

【讨论】:

这个问题与 Web API 控制器有关,而不是 MVC 控制器。【参考方案6】:

我希望这是您正在寻找的解决方案

在startup.cs中

在配置方法中添加以下代码

app.UseSession();

在 ConfigureServices 方法中添加以下代码

  services.AddDistributedMemoryCache();
    services.AddSession(x=> 
    
       x.Cookie.Name = "Cookie name";
       x.IdleTimeout = TimeSpan.FromMinutes(5); // idle time for the session                
    );

我在类文件示例中创建会话:UserLogin.cs

    private ISession session => httpContext.Session;
        public UserLogin(HttpContext httpContext)
        
            this.httpContext = httpContext;
        
   private void SetSession(ClassInstance ObjOutput)
        

            session.SetString("SessionID", ObjOutput.strSession.ToString()); 
        

在上面的代码中,我将 HttpContext 注入到类中,而 strSession 是我将从 SP 获取的 GUID,

要在 api 中验证会话,请创建操作过滤器,在该过滤器中,您可以从 OnActionExecuting(ActionExecutingContext context) 方法的上下文中获取会话

context.HttpContext.Request.Headers["Session"]; this line will get the session from header
context.HttpContext.Session.GetString("SessionID"); this line will get the current session 

如果两者都匹配,如果不匹配也没关系

你可以使用下面的代码告诉会话过期

string strExceptionOutput = JsonConvert.SerializeObject(new response()
                
                    StatusCode = (int)HttpStatusCode.InternalServerError,
                    message = "Session Expired"
                );
                response.ContentType = "application/json";
                context.Result = new BadRequestObjectResult(strExceptionOutput);

【讨论】:

以上是关于如何创建和访问 Session .net core api?的主要内容,如果未能解决你的问题,请参考以下文章

.net core利用actionFilter实现session过期自动跳转

.net core利用actionFilter实现session过期自动跳转

如何在.net core 2 的启动中访问 IConfigurationRoot?

ASP.NET Core 中简单Session登录校验

ASP.NET Core 2.1 API JWT 令牌 Session.id 在每次请求时都会更改

如何在 ASP.NET Core 中保持对象活动?