如何从 blazor 中的 .cs 文件访问浏览器本地存储?

ily*_*rol 5 c# browser local-storage blazor blazor-server-side

首先,我可以访问 .razor 页面中的本地存储数据。我的意思是我无法访问 .cs 文件中的本地存储数据。我怎样才能访问?

_Imports.razor:

@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
@inject ProtectedLocalStorage protectedLocalStorage
Run Code Online (Sandbox Code Playgroud)

任何人 .razor 文件:

await protectedLocalStorage.SetAsync(key, JsonSerializer.Serialize(instance));
Run Code Online (Sandbox Code Playgroud)

上面的代码适用于我,但我想另外从 .cs 文件调用 protectedLocalStorage。

PS抱歉语法错误

编辑:我在startup.cs中使用IHttpClientFactory,我想在api请求之前添加令牌作为标头。

启动.cs

    services.AddHttpClient("api", hc =>
    {
        hc.BaseAddress = new Uri("http://localhost:5000/");

        string tokenVal = tokenService.GetToken();

        if (!String.IsNullOrEmpty(tokenVal))
            hc.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenVal);
    });
Run Code Online (Sandbox Code Playgroud)

我想从这个 .cs 文件的本地存储中获取令牌值

public class TokenService : ITokenService
{
    private IHttpContextAccessor httpContextAccessor;

    public TokenService(IHttpContextAccessor HttpContextAccessor, IProtected) => httpContextAccessor = HttpContextAccessor;

    public string GetToken()
    {
        return "";
    }
}
Run Code Online (Sandbox Code Playgroud)

Con*_*Low 8

如何从 blazor 中的 .cs 文件访问浏览器本地存储?

ASP.NET 支持大多数构造函数中的注入。扩展OP的例子:

// Startup.cs -> ConfigureServices(IServiceCollection services)
    // Probably not necessary in your case but, to be thorough:
    services.AddScoped<ProtectedLocalStorage>();

// SomeFile.cs
public class TokenService : ITokenService
{
    // Ignore for the moment that these are being used in the same context
    private IHttpContextAccessor httpContextAccessor;
    private readonly ProtectedBrowserStorage _storage;

    // Injection can happen here in ASP.NET
    public TokenService(
        IHttpContextAccessor HttpContextAccessor, 
        ProtectedBrowserStorage storage) 
    {
        httpContextAccessor = HttpContextAccessor;
        // injection works but the PBS service might not: see below
        _storage = storage;
    }

    //..
}
Run Code Online (Sandbox Code Playgroud)

但是,我不推荐这样做ProtectedBrowserStorage,因为它IJSRuntime在幕后使用。如果您尝试在非 javascript 感知上下文中使用它(例如,在Startup.Configure客户端仍在等待响应且无法执行 javascript 期间),您将遇到错误。在 Blazor 中,ProtectedBrowserStorage只能从 Blazor 组件直接或间接调用;为了简单起见,请将其包装在仅与组件一起使用的类中,或者将其保留在组件本身中。

因此,如果您尝试执行此操作:

我在startup.cs中使用IHttpClientFactory,我想在api请求之前添加令牌作为标头。

ProtectedBrowserStorage不是适合您的工具。使用 cookie 或其他网络服务器技术。


ily*_*rol 5

我最后是如何解决的:

\n

我创建了继承 AuthenticationStateProvider 的自定义身份验证类。然后我设计了所有的检查流程在ProtectedLocalStorage上解决。

\n

认证服务

\n
    public class AuthenticationService : AuthenticationStateProvider\n    {\n        private const string USER_SESSION_OBJECT_KEY = "user_session_obj";\n        private const string ACCESS_TOKEN = "accesstoken";\n        private const string USER_PERMISSIONS = "userpermissions";\n\n        private readonly ProtectedLocalStorage _protectedLocalStorage;\n        private readonly IHttpContextAccessor _httpContextAccessor;\n\n        public AuthenticationService(ProtectedLocalStorage protectedSessionStore, IHttpContextAccessor httpContextAccessor)\n        {\n            _protectedLocalStorage = protectedSessionStore;\n            _httpContextAccessor = httpContextAccessor;\n        }\n\n        public string IpAddress => _httpContextAccessor?.HttpContext?.Connection?.RemoteIpAddress?.ToString() ?? string.Empty;\n\n        private User User { get; set; }\n        private List<UserPermission> UserPermissionList { get; set; }\n\n        public override async Task<AuthenticationState> GetAuthenticationStateAsync()\n        {\n            try\n            {\n                User userSession = await GetUserSession();\n                List<UserPermission> userPermissions = await GetUserPermission();\n\n                if (userSession != null)\n                    return await GenerateAuthenticationState(userSession, userPermissions);\n                return await GenerateEmptyAuthenticationState();\n            }\n            catch\n            {\n                await LogoutAsync();\n                return null;\n            }\n          \n        }\n\n        public async Task LoginAsync(User user,List<UserPermission> userPermissions)\n        {\n            await SetUserSession(user);\n            await SetUserPermissionSession(userPermissions);\n\n            NotifyAuthenticationStateChanged(GenerateAuthenticationState(user, userPermissions));\n        }\n\n        public async Task LogoutAsync()\n        {\n            //await SetUserSession(null);\n            RefreshUserSession(null);\n            await _protectedLocalStorage.DeleteAsync(USER_SESSION_OBJECT_KEY);\n            await _protectedLocalStorage.DeleteAsync(ACCESS_TOKEN);\n            await _protectedLocalStorage.DeleteAsync(USER_PERMISSIONS);\n\n            NotifyAuthenticationStateChanged(GenerateEmptyAuthenticationState());\n        }\n\n        public async Task<User> GetUserSession()\n        {\n            if (User != null)\n                return User;\n            //TODO burda localUserJson get yaparken hata al\xc4\xb1yor. try catch i\xc5\x9fi \xc3\xa7\xc3\xb6zmezse buraya tekrardan bak\xc4\xb1lacak.\n            try\n            {\n                var localUserJson = await _protectedLocalStorage.GetAsync<string>(USER_SESSION_OBJECT_KEY);\n\n                if (string.IsNullOrEmpty(localUserJson.Value))\n                    return null;\n\n                return RefreshUserSession(JsonConvert.DeserializeObject<User>(localUserJson.Value));\n            }\n            catch\n            {\n                await LogoutAsync();\n                return null;\n            }\n        }\n        public async Task<List<UserPermission>> GetUserPermission()\n        {\n            if (UserPermissionList != null)\n                return UserPermissionList;\n            try\n            {\n                var localUserPermissionJson = await _protectedLocalStorage.GetAsync<string>(USER_PERMISSIONS);\n\n                if (string.IsNullOrEmpty(localUserPermissionJson.Value))\n                    return null;\n\n                return RefreshUserPermissionSession(JsonConvert.DeserializeObject<List<UserPermission>>(localUserPermissionJson.Value));\n            }\n            catch\n            {\n                await LogoutAsync();\n                return null;\n            }\n        }\n        private async Task SetUserSession(User user)\n        {\n            RefreshUserSession(user);\n\n            await _protectedLocalStorage.SetAsync(USER_SESSION_OBJECT_KEY, JsonConvert.SerializeObject(user));\n        }\n\n        private async Task SetUserPermissionSession(List<UserPermission> userPermissions)\n        {\n            RefreshUserPermissionSession(userPermissions);\n\n            await _protectedLocalStorage.SetAsync(USER_PERMISSIONS, JsonConvert.SerializeObject(userPermissions));\n        }\n\n        private User RefreshUserSession(User user) => User = user;\n        private List<UserPermission> RefreshUserPermissionSession(List<UserPermission> userPermission) => UserPermissionList = userPermission;\n\n        private Task<AuthenticationState> GenerateAuthenticationState(User user, List<UserPermission> userPermission)\n        {\n            ClaimsIdentity claimsIdentity = new ClaimsIdentity(new[]\n            {\n                new Claim(ClaimTypes.Name, user.Id.ToString()),\n                new Claim(ClaimTypes.Role, userPermission.ToString()),\n            }, "auth");\n\n            ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(claimsIdentity);\n            return Task.FromResult(new AuthenticationState(claimsPrincipal));\n        }\n\n        private Task<AuthenticationState> GenerateEmptyAuthenticationState() => Task.FromResult(new AuthenticationState(new ClaimsPrincipal()));\n    }\n
Run Code Online (Sandbox Code Playgroud)\n

然后我在startup.cs中注册了这个类

\n

启动

\n
services.AddScoped<AuthenticationStateProvider, AuthenticationService>();\n
Run Code Online (Sandbox Code Playgroud)\n

在更改页面期间,身份验证系统会中断显示页面以检查其是否通过以下代码进行身份验证。

\n

_进口

\n
@attribute [Authorize]\n
Run Code Online (Sandbox Code Playgroud)\n

*您可以在登录页面设置本地存储。您可以通过这种方式创建自己的检查方式。

\n