【发布时间】:2020-09-10 14:31:37
【问题描述】:
我有一个带有用户服务的 Blazor Webassembly 应用程序,该服务旨在通过 API 检索用户的详细信息。服务如下所示:
public class UserDataService : IUserDataService
{
public readonly HttpClient _HttpClient;
public UserDataService(HttpClient httpClientDI)
{
_HttpClient = httpClientDI;
}
public async Task<User> GetUserInfo()
{
try
{
return await _HttpClient.GetFromJsonAsync<User>("api/users/MyUserInfo");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
}
}
API 专门设计用于从客户端请求中读取加密的 cookie。此 cookie 包含用户的电子邮件地址,用户信息服务使用此 cookie 来检索更详细的用户信息集。
[HttpGet("MyUserInfo")]
public User MyUserInfo()
{
var myCookie = HttpContext.Request.Cookies.FirstOrDefault(c => c.Key == "MyCookie");
var userMask = JsonConvert.DeserializeObject<AuthUserMask>(Protector.Unprotect(myCookie.Value));
var user = UserService.Find(userMask.Email).FirstOrDefault();
return user;
}
当我运行 Web 应用程序时,我能够验证 cookie 是否存在于浏览器中,但是当应用程序向 API 发出请求时,cookie 不包括在内。事实上,该请求根本不包含来自客户端的任何 cookie。
我对 Blazor 完全陌生,我不确定是否存在适用于此类场景的任何约定,但目前我只是想让这个新的 Web 应用程序与我们现有的服务一起使用。有没有办法确保包含 cookie?我可能做错了什么?
提前感谢您的帮助。
编辑
这是创建 cookie 的代码。它是验证用户是否经过身份验证的更大方法的一部分,但这是相关部分:
{
var userJson = JsonConvert.SerializeObject(new AuthUserMask()
{
Email = user.Email,
isActive = user.IsActive
});
var protectedContents = Protector.Protect(userJson);
HttpContext.Response.Cookies.Append("MyCookie", protectedContents, new CookieOptions()
{
SameSite = SameSiteMode.None,
Secure = true,
Path = "/",
Expires = DateTime.Now.AddMinutes(60)
});
HttpContext.Response.Redirect(returnUrl);
}
编辑 2
在 UserDataService 中尝试了以下操作,看看会发生什么:
public async Task<User> GetUserInfo()
{
try
{
_HttpClient.DefaultRequestHeaders.Add("Test", "ABC123");
return await _HttpClient.GetFromJsonAsync<User>("api/users/MyUserInfo");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
}
不幸的是,结果是一样的 - RequestCookieCollection 在访问 API 时是完全空的。
【问题讨论】:
-
能否也包括写入或配置cookie的代码?某些设置可能会影响浏览器将其正确包含在您的请求中的能力。
-
看起来将您的路径设置为“/”可能是问题所在。查看文档,如果请求是针对已发布域的根目录,这听起来只会包含您的 cookie。您介意在 CookieOptions 中删除该属性并查看问题是否仍然存在吗? docs.microsoft.com/en-us/dotnet/api/…
-
如果我没看错,您正试图将此 cookie 发送到服务器,在这种情况下,它不应该是
Request而不是Response?可以试试加httpclient.DefaultRequestHeaders.Add("MyCookie", "SomeCokkieContent"); -
情节变厚了。唯一引起我注意的是 Secure = true。当设置为 true 时,UI 和 API 都必须使用 HTTPS 进行所有通信。你也可以仔细检查一下。如果这不起作用,我赞成提请注意这个问题。祝你好运。
-
我在这里有点困惑,当您向服务器发布内容时,您试图在标头中包含某些内容,或者您正在寻找服务器在响应标头中发送的内容?
_HttpClient.DefaultRequestHeaders.Add("Test", "ABC123");后面应该跟一个 POST 请求,而不是 GET,如果您的范围是将它发送到服务器。
标签: c# asp.net-core cookies dotnet-httpclient blazor-webassembly