.NET Core 8 SSR Blazor页面间安全传参(无需URL查询字符串)
解决.NET Core 8 SSR Blazor身份验证场景下跨页面安全传递数据的问题
针对跳转页面时数据丢失、URL传参不安全的问题,推荐以下几种服务器端解决方案,既避免数据暴露,又能满足当前字符串和未来复杂对象传递的需求:
1. 使用ASP.NET Core Session存储
Session是服务器端会话存储,数据保存在服务器(默认内存,可配置分布式缓存),前端无法直接获取,安全性高。
配置Session
在Program.cs中添加Session服务与中间件:
builder.Services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(30); options.Cookie.HttpOnly = true; options.Cookie.IsEssential = true; }); // 需放在app.UseRouting()之后、app.UseAuthorization()之前 app.UseSession();
在Home.razor中存储数据
@inject IHttpContextAccessor HttpContextAccessor @inject NavigationManager NavigationManager @code { private string CurrentTheme = "bootstrap-dark.css"; private void NavigateToLogin() { HttpContextAccessor.HttpContext.Session.SetString("GlobalTheme", CurrentTheme); NavigationManager.NavigateTo("/login"); } }
在Login.razor中读取数据
@inject IHttpContextAccessor HttpContextAccessor @code { private string? GlobalTheme; protected override void OnInitialized() { GlobalTheme = HttpContextAccessor.HttpContext.Session.GetString("GlobalTheme"); } }
传递复杂对象:将对象序列化为JSON字符串存入Session,读取时反序列化即可:
// 存储对象 var userSettings = new UserSettings { Theme = "bootstrap-dark.css", Layout = "Sidebar" }; var json = JsonSerializer.Serialize(userSettings); HttpContextAccessor.HttpContext.Session.SetString("UserSettings", json); // 读取对象 var json = HttpContextAccessor.HttpContext.Session.GetString("UserSettings"); var userSettings = JsonSerializer.Deserialize<UserSettings>(json);
2. 使用TempData传递短期数据
TempData专门用于跨请求传递一次性数据,读取后自动删除(可通过Keep()保留),适合页面跳转场景。
在Home.razor中存储数据
@inject ITempDataDictionary TempData @inject NavigationManager NavigationManager @code { private string CurrentTheme = "bootstrap-dark.css"; private void NavigateToLogin() { TempData["GlobalTheme"] = CurrentTheme; NavigationManager.NavigateTo("/login"); } }
在Login.razor中读取数据
@inject ITempDataDictionary TempData @code { private string? GlobalTheme; protected override void OnInitialized() { GlobalTheme = TempData["GlobalTheme"] as string; // 若需后续继续读取,调用 TempData.Keep("GlobalTheme"); } }
3. 注册全局状态服务(适合长期全局数据)
如果主题是需多页面长期使用的全局状态,推荐注册Scoped服务,每个用户会话对应一个实例,数据在会话周期内有效。
定义状态服务
public class AppStateService { public string GlobalTheme { get; set; } = "bootstrap.css"; // 未来可扩展复杂对象 public UserSettings? UserSettings { get; set; } } // 复杂对象示例 public class UserSettings { public string Layout { get; set; } = "Default"; public bool NotificationsEnabled { get; set; } = true; }
在Program.cs中注册服务
builder.Services.AddScoped<AppStateService>();
在Home.razor中设置数据
@inject AppStateService AppState @inject NavigationManager NavigationManager @code { private void NavigateToLogin() { AppState.GlobalTheme = "bootstrap-dark.css"; // 复杂对象赋值 // AppState.UserSettings = new UserSettings { Layout = "Sidebar" }; NavigationManager.NavigateTo("/login"); } }
在Login.razor中读取数据
@inject AppStateService AppState @code { protected override void OnInitialized() { var currentTheme = AppState.GlobalTheme; var userSettings = AppState.UserSettings; } }
此方案无需手动管理存储逻辑,通过依赖注入直接访问全局状态,适合长期维护的全局数据,扩展复杂对象也更便捷。
内容的提问来源于stack exchange,提问作者DaveK
相关产品推荐
相关产品推荐

