使用 asp.net 和 redis 缓存进行部署槽交换后如何保留会话

问题描述 投票:0回答:1

我有一个 asp.net 应用程序(.net 版本 6),配置如下:

var redisConnectionString = "fakestring";

builder.Services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = redisConnectionString;
});

builder.Services.AddSession(options =>
{
    options.Cookie.Name = "fakecookiename";
    options.IdleTimeout = TimeSpan.FromMinutes(builder.Configuration.GetValue<int>("SessionDefaults:IdleTimeoutInMinutes"));
    options.Cookie.SameSite = SameSiteMode.None;
    options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});

我使用最新的 StackExchange.Redis nuget 包 (2.7.33),因为在交换插槽时出现了多次丢失 Redis 连接的问题,直到再次稳定之前长达 20 分钟。

现在我的 Redis 连接在交换时看起来很稳定,但出现了新问题。

交换插槽后(所有应用程序设置都不是特定于插槽的),我的浏览器会获得一个新的会话 Cookie。所以我实际上丢失了我的会话,导致我的前端应用程序中出现会话过期异常。

有没有办法在部署槽交换后保留会话 cookie?

非常感谢您的帮助。

亲切的问候

asp.net redis azure-web-app-service session-cookies azure-deployment-slots
1个回答
0
投票

我尝试了您的代码,并且能够在部署槽交换后成功保留会话令牌。

交换插槽后(所有应用程序设置都不是特定于插槽的),我的浏览器会获得一个新的会话 Cookie。所以我实际上丢失了我的会话,导致我的前端应用程序中出现会话过期异常。

避免上述问题

  • 确保应用程序设置(如 Redis 连接字符串)配置正确并且在部署槽中保持一致。应用程序设置必须跨槽共享和同步。

这是我的Program.cs:


using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using StackExchange.Redis;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Caching.StackExchangeRedis;
using Microsoft.AspNetCore.DataProtection;
using System.Runtime.Intrinsics.X86;

var builder = WebApplication.CreateBuilder(args);
var configuration = builder.Configuration;

var fakeRedisConnectionString = "fakestring";
builder.Services.AddStackExchangeRedisCache(options =>
{
   options.Configuration = fakeRedisConnectionString;
});

builder.Services.AddSession(options =>
{
   options.Cookie.Name = "fakecookiename";
   options.IdleTimeout = TimeSpan.FromMinutes(builder.Configuration.GetValue<int>("SessionDefaults:IdleTimeoutInMinutes"));
   options.Cookie.SameSite = SameSiteMode.None; 
   options.Cookie.SecurePolicy = CookieSecurePolicy.Always; 
});

var redisConnectionString = configuration.GetConnectionString("RedisConnection");
builder.Services.AddStackExchangeRedisCache(options =>
{
   options.Configuration = redisConnectionString;
   options.InstanceName = "YourAppInstance"; 
});

builder.Services.AddSession(options =>
{
   options.Cookie.Name = ".YourApp.Session"; 
   options.IdleTimeout = TimeSpan.FromMinutes(configuration.GetValue<int>("SessionDefaults:IdleTimeoutInMinutes"));
   options.Cookie.SameSite = SameSiteMode.Strict; 
   options.Cookie.SecurePolicy = CookieSecurePolicy.Always; 
   options.Cookie.HttpOnly = true; 
   options.Cookie.IsEssential = true; 
});

builder.Services.AddDataProtection()
   .PersistKeysToStackExchangeRedis(ConnectionMultiplexer.Connect("your redisconnection string"),"DataProtection-Keys");

var app = builder.Build();
app.UseSession();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
   endpoints.MapGet("/", async context =>
   {
       context.Session.SetString("TestKey", "TestValue");
       await context.Response.WriteAsync("Session value set.");
   });
   endpoints.MapGet("/get", async context =>
   {
       var value = context.Session.GetString("TestKey");
       await context.Response.WriteAsync($"Session value: {value}");
   });
});

app.Run();

Appsettings.json:

{
    "ConnectionStrings": {
        "RedisConnection": "redis connection string"
    },
    "SessionDefaults": {
        "IdleTimeoutInMinutes": 20
    }
}

本地输出:

enter image description here

部署后的输出: enter image description here

这是插槽交换后的输出:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.