我正在做一个项目,使用Redis作为分布式缓存来存储我的会话数据。我的应用程序应该首先检查缓存是否有会话对象,如果没有,它应该从DB获取数据。问题是我无法访问会话密钥本身,而SessionMiddleware使用会话密钥作为Redis缓存中的密钥。我想出了一些解决方案:
- 使用session . loadasync()方法来更新应用程序会话状态,并检查session . load是否存在。键保存一些数据。
- 找到一种方法来解密cookie会话,它是与请求一起发送的,并从中获得密钥
- 为SessionMiddleware创建自定义修改并覆盖默认行为以提取密钥会话
但是我想知道是否有一个更好,更简单,更优雅的方式来获得这个会话键在应用程序中,并使查询到Redis,如果关键会话存在。是否有一些服务,管理器等从传入请求中提取密钥会话并使其可用?
好的,我找到了John-Luke Laue"提供的解决方案。在这篇文章https://stackoverflow.com/a/40685514/12543959.
重要!解决方案是好的但你仍然可以得到一个错误:
An unhandled exception has occurred while executing the request.
System.Security.Cryptography.CryptographicException: The payload was invalid.
at Microsoft.AspNetCore.DataProtection.Managed.ManagedAuthenticatedEncryptor.Decrypt(ArraySegment`1 protectedPayload, ArraySegment`1 additionalAuthenticatedData)
at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status)
at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.DangerousUnprotect(Byte[] protectedData, Boolean ignoreRevocationErrors, Boolean& requiresMigration, Boolean& wasRevoked)
at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData)
问题在一个地方,变量用途的值,需要在CreateProtector()中作为字符串类型的参数:
var protectorPurpose = "whatever purpose you want";
_dataProtector = dataProtectionProvider.CreateProtector(protectorPurpose);
因为会话密钥的加密是在SessionMiddleware中进行的,所以正确的值应该是"SessionMiddleware"。类型为string,代码应该如下所示:
_dataProtector = dataProtectionProvider.CreateProtector(nameof(SessionMiddleware));