我有一个MVC登录表单:
[HttpPost]
public ActionResult Login(LoginViewModel viewModel)
{
if (viewModel.Username == "alex" && viewModel.Password == "password")
{
FormsAuthentication.SetAuthCookie(viewModel.Username, false);
return RedirectToAction("Index", "Home");
}
return View();
}
使用MVC登录操作的控制台应用客户端:
private static void GetPerson()
{
Console.WriteLine("Username:");
string username = Console.ReadLine();
Console.WriteLine("Password:");
string password = Console.ReadLine();
using (HttpClient httpClient = new HttpClient())
{
HttpRequestMessage authRequest = new HttpRequestMessage();
authRequest.Method = HttpMethod.Post;
authRequest.RequestUri = new Uri(@"http://localhost:4391/Account/Login");
authRequest.Content = new FormUrlEncodedContent(new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("Username", username),
new KeyValuePair<string, string>("Password", password)
});
HttpResponseMessage authResponse = httpClient.SendAsync(authRequest).Result;
IEnumerable<string> cookieValues;
authResponse.Headers.TryGetValues("Set-Cookie", out cookieValues);
}
}
问题:authResponse.Headers.TryGetValues(&#34; Set-Cookie&#34;,out cookieValues)没有找到&#34; Set-Cookie&#34;标题所以cookieValues出现了&#34; null&#34;。
我在MVC中运行Fiddler for Login操作,这是我得到的:
HTTP/1.1 302 Found
Cache-Control: private
Content-Type: text/html; charset=utf-8
Location: /
Server: Microsoft-IIS/8.0
X-AspNetMvc-Version: 5.1
X-AspNet-Version: 4.0.30319
Set-Cookie: .ASPXAUTH=A6A22208AECA1F3E25B43C834BE058A5019F3A9C55AED099FFAD5B0FE7B289EC2C3F87C157B0C1ED338D1DF0A6469E6C5DE8D9DB7A99D54D992EA10F26424BA579C262B7CD247CA4193879E058A233B7A0BC98E10503440B79EB988239C43696; path=/; HttpOnly
X-SourceFiles: =?UTF-8?B?YzpcdXNlcnNcYWxleGFuZGVyXGRvY3VtZW50c1x2aXN1YWwgc3R1ZGlvIDIwMTNcUHJvamVjdHNcRm9ybVZhbHVlc0F1dGhXZWJBUElcRm9ybVZhbHVlc0F1dGhXZWJBUElcQWNjb3VudFxMb2dpbg==?=
X-Powered-By: ASP.NET
Date: Sat, 19 Apr 2014 20:09:23 GMT
Content-Length: 428
Fiddler表示我得到了&#34; Set-Cookie&#34;回来但为什么HttpClient没有看到它?
答案 0 :(得分:1)
想出来 - MVC动作发送2个回复一个回复一个cookie,第二个回复没有cookie。 HttpClient显示最新的响应,这就是为什么它无法找到&#34; Set Cookie&#34;报头中。
但是!
似乎HttpClient从内部的第一个响应中保存cookie,并且在同一域下的安全页面上请求HttpClient自动应用该保存的cookie。
在我的例子中,如果我将连接到&#34; localhost:4391 / api / Person / 1&#34;使用HttpClient,我将获得未经授权。所以我的目标是去&#34; localhost:4391 /帐户/登录&#34;使用HttpClient,登录,获取生成的cookie然后转到&#34; localhost:4391 / api / Person / 1&#34;并发送该cookie,但正如我之前提到的,HttpClient自动执行此操作,我不需要从第一个请求中提取cookie到登录页面。
所以下面的代码可以根据需要运行!
private static void GetPerson()
{
Console.WriteLine("Username:");
string username = Console.ReadLine();
Console.WriteLine("Password:");
string password = Console.ReadLine();
HttpClient httpClient = new HttpClient();
HttpRequestMessage authRequest = new HttpRequestMessage();
authRequest.Method = HttpMethod.Post;
authRequest.RequestUri = new Uri(@"http://localhost:4391/Account/Login");
authRequest.Content = new FormUrlEncodedContent(new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("Username", username),
new KeyValuePair<string, string>("Password", password)
});
HttpResponseMessage authResponse = httpClient.SendAsync(authRequest).Result;
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, @"http://localhost:4391/api/Person/1");
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = httpClient.SendAsync(request).Result;
if (!response.IsSuccessStatusCode)
{
Console.WriteLine("Username or password is incorrect");
return;
}
response.Content.ReadAsAsync<Person>().ContinueWith((x) => {
Person person = x.Result;
Console.WriteLine("First name: {0}", person.FirstName);
Console.WriteLine("Last name: {0}", person.LastName);
});
}
但是如果我在控制器中的动作看起来如此,那么回到抓住那个cookie我就能完成它:
[HttpPost]
public ActionResult Login(string username, string password)
{
if (username == password)
{
FormsAuthentication.SetAuthCookie(username, true);
return new HttpStatusCodeResult(HttpStatusCode.OK);
}
return new HttpUnauthorizedResult();
}
答案 1 :(得分:0)
你可以尝试像这样设置auth cookie吗
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, authTicket);
Response.Cookies.Add(cookie);
参考这篇文章,它可能会有所启发。 http://weblog.west-wind.com/posts/2012/Nov/29/SetCookie-Headers-getting-stripped-in-ASPNET-HttpHandlers
答案 2 :(得分:0)
我研究了很多,但在另一种语言的网站上找到了一个。解决方案是为会话开始和结束添加一个空的事件处理程序: protected void Session_Start(object sender,EventArgs e) { } protected void Session_End(object sender,EventArgs e) { }