Art*_*nes 5 asp.net cookies asp.net-web-api
我正在使用Visual Studio 2012开发带有WPF(.NET 4.0)客户端的ASP WebAPI(ASP MVC 4)应用程序.客户端需要登录到服务器.我使用FormsAuthentication和身份验证cookie登录.登录已经在ASP MVC中正常工作.
问题是,尽管登录在服务器上成功执行并且cookie被发送回客户端,但是在后续调用服务器时不会发送cookie,即使它CookieContainer与auth cookie集重用.
这是代码的简化版本:
客户
public async Task<UserProfile> Login(string userName, string password, bool rememberMe)
{
using (var handler = new HttpClientHandler() { CookieContainer = this.cookieContainer })
using (var httpClient = new HttpClient(handler))
{
httpClient.BaseAddress = new Uri("http://localhost:50000/");
httpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var result = await httpClient.PostAsJsonAsync("api/auth/login", new
{
username = userName,
password = password,
rememberMe = rememberMe
});
result.EnsureSuccessStatusCode();
var userProfile = await result.Content.ReadAsAsync<UserProfile>();
if (userProfile == null)
throw new UnauthorizedAccessException();
return userProfile;
}
}
public async Task<ExamSubmissionResponse> PostItem(Item item)
{
using (var handler = new HttpClientHandler() { CookieContainer = this.cookieContainer })
using (var httpClient = new HttpClient(handler))
{
httpClient.BaseAddress = new Uri("http://localhost:50000/");
var result = await httpClient.PostAsJsonAsync("api/Items/", item);
}
}
Run Code Online (Sandbox Code Playgroud)
服务器
[HttpPost]
public HttpResponseMessage Login(LoginModel model)
{
if (this.ValidateUser(model.UserName, model.Password))
{
// Get user data from database
string userData = JsonConvert.SerializeObject(userModel);
var authTicket = new FormsAuthenticationTicket(
1,
model.UserName,
DateTime.Now,
DateTime.Now.AddMinutes(10 * 15),
model.RememberMe,
userData
);
string ticket = FormsAuthentication.Encrypt(authTicket);
var cookie = new CookieHeaderValue(FormsAuthentication.FormsCookieName, ticket);
var response = Request.CreateResponse(HttpStatusCode.Created, userModel);
response.Headers.AddCookies(new CookieHeaderValue[] { cookie });
return response;
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
首先,我使用Fiddler2调试了问题(我使用基地址作为" http://localhost.fiddler:50000/"来查看本地流量).然后我怀疑小提琴手可能会干扰,所以我只是使用Visual Studio 2012进行了调试.
我试过并验证了什么:
Login方法到达服务器
用户通过客户端发送的数据进行成功验证
cookie在服务器上设置
cookie在响应中(用fiddler验证)
操作后,cookie位于CookieContainer中.这里有一个奇怪的事情:容器中cookie的域名设置为"localhost"(使用VS2012调试器验证).不应该是" http://localhost:50000"吗?当我尝试使用cookieContainer.GetCookies(new Uri("http://localhost:50000"))它获取容器的cookie时,什么都不返回.当我尝试使用cookieContainer.GetCookies(new Uri("localhost"))它时,给我一个无效的Uri错误.不知道这里发生了什么.
在PostItem请求发出之前,cookie就在容器中.httpClient.PostAsJsonAsync到达语句时,容器在HttpClient中正确设置.
cookie没有发送到服务器(我用fiddler和Application_PostAuthenticateRequestGlobal.asax.cs 中的方法检查它,验证this.Request.Cookies)
我怀疑由于域名不匹配而没有发送cookie CookieContainer,但是为什么域名CookieContainer在第一时间没有设置?
您的问题是您没有在从Web Api控制器发回的cookie上设置任何路径.
有两件事可以控制发送cookie的位置:
关于域名,共识似乎是端口号不再(但仍可能)成为评估cookie域的一个因素.有关端口号如何影响域的详细信息,请参阅此问题.
关于路径:Cookie与其域中的特定路径相关联.在您的情况下,Web Api发送cookie而不指定其路径.默认情况下,cookie将与创建cookie的请求/响应的路径相关联.
在您的情况下,cookie将具有路径api/auth/login.这意味着cookie将被发送到此路径的子路径(缺少更好的术语),但不会发送到父路径或兄弟路径.
要测试这个,请尝试:
cookieContainer.GetCookies(new Uri("http://localhost/api/auth/login")
Run Code Online (Sandbox Code Playgroud)
这应该给你cookie.这应该是这样的:
cookieContainer.GetCookies(new Uri("http://localhost/api/auth/login/foo/bar")
Run Code Online (Sandbox Code Playgroud)
另一方面,这些将找不到cookie:
cookieContainer.GetCookies(new Uri("http://localhost/")
cookieContainer.GetCookies(new Uri("http://localhost/api/")
cookieContainer.GetCookies(new Uri("http://localhost/api/auth/")
cookieContainer.GetCookies(new Uri("http://localhost/api/auth/foo")
cookieContainer.GetCookies(new Uri("http://localhost/api/Items/")
Run Code Online (Sandbox Code Playgroud)
要解决此问题,只需在发送共鸣之前将路径"/"(或者可能是"/ api")添加到cookie:
...
string ticket = FormsAuthentication.Encrypt(authTicket);
var cookie = new CookieHeaderValue(FormsAuthentication.FormsCookieName, ticket);
cookie.Path = "/";
var response = Request.CreateResponse(HttpStatusCode.Created, userModel);
response.Headers.AddCookies(new CookieHeaderValue[] { cookie });
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8337 次 |
| 最近记录: |