我正在编写Xamarin跨平台移动应用程序。服务器是一个SpringMVC服务器,它使用JWT令牌对每个端点/ Web服务进行身份验证。所以基本上,当我第一次向webservice发出请求时,在我需要点击/authorize
POST端点发送我的电子邮件和密码之前,端点响应将在"Cookie"
标头中包含标识为"AUTH_TOKEN={MD5-String}"
的authenticaton标记。一旦我得到令牌,我就会将请求发送给端点,比如说/feed
。但我的问题是,我无法弄清楚在C#HttpClient
中设置“Cookie”标头的方式。我尝试了一切,但是endpoing只是继续响应登录屏幕html而不是实际的JSON响应。我在Postman和其他REST客户端尝试了相同的步骤,它工作。所以这意味着我做错了什么。这里是我的代码:来自C#HttpClient的针对Spring服务器JWT令牌的身份验证
public class RestService : IRestService
{
HttpClient client;
HttpClientHandler handler;
CookieContainer cookies;
string authToken;
public List<Feed> FeedItems { get; private set; }
public RestService()
{
cookies = new CookieContainer();
handler = new HttpClientHandler();
handler.UseCookies = true; //Otherwise It'll not use the cookies container!!
handler.CookieContainer = cookies;
client = new HttpClient(handler);
client.MaxResponseContentBufferSize = 256000;
}
public async Task<List<Role>> GetFeedDataAsync()
{
//Request credentials
//Credentials validation
var credentials = new HalliganCredential()
{
email = Constants.Username,
password = Constants.Password
};
var jsonCredentials = JsonConvert.SerializeObject(credentials);
var jsonCredentialsContent = new StringContent(jsonCredentials, Encoding.UTF8, "application/json");
var authorizeUri = new Uri(Constants.AuthorizeEndpoint);
var authorizeResponse = await client.PostAsync(authorizeUri, jsonCredentialsContent);
if (authorizeResponse.IsSuccessStatusCode)
{
//If authentication went OK
IEnumerable<Cookie> responseCookies = cookies.GetCookies(authorizeUri).Cast<Cookie>();
foreach (Cookie cookie in responseCookies)
{
if (cookie.Name.Equals("AUTH-TOKEN"))
{
authToken = cookie.Value;
}
}
}
else
{
//Authentication failed throw error
throw new HttpRequestException("Authentication failed");
}
FeedItems = new List<Feed>();
//Making the GET request
var uri = new Uri(string.Format(Constants.FeedEnpoint, string.Empty));
try
{
cookies.Add(uri, new Cookie("Cookie", string.Format("AUTH_TOKEN={0}", authToken)));
client.DefaultRequestHeaders.Add("Cookie", string.Format("AUTH_TOKEN={0}", authToken));
handler.CookieContainer.Add(uri, new Cookie("Cookie", string.Format("AUTH_TOKEN={0}", authToken)));
var response = await client.GetAsync(uri);
response.EnsureSuccessStatusCode();
//Credentials validation
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
FeedItems = JsonConvert.DeserializeObject<List<Feed>>(content);
}
}
catch (Exception ex)
{
Debug.WriteLine(@"ERROR {0}", ex.Message);
}
return FeedItems;
}
}
当我到达行var content = await response.Content.ReadAsStringAsync();
的响应是一个HTML字符串,而不是实际的JSON响应。
我尝试了其他几个关键值的标题,虽然"Cookie"
是一个邮政工作的人。
我试过"Set-Cookie"
,"set-cookie"
,"Set-Cookie"
,设置标题为"AUTH_TOKEN"
。我在不同的地方尝试了所有这些试验,例如在cookie
CookieContainer
,handler
CookieContainer
和client.DefaultRequestHeaders
中添加它们。
我试着打开和关闭handler.UseCookies = true; //Otherwise It'll not use the cookies container!!
行。
任何帮助将受到欢迎!
UPDATE
我试着用建议的解决方案之一,但没有工作,我想无论是在真假UseCookies。
//Making the GET request
var baseAddress = new Uri("http://app.******.io");
using (var handler = new HttpClientHandler { UseCookies = true })
using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
{
var message = new HttpRequestMessage(HttpMethod.Get, "/api/v1/feed?api_key=sarasa");
message.Headers.Add("Cookie", string.Format("AUTH_TOKEN={0}", authToken));
message.Headers.Add("Cookie", string.Format("AUTH_TOKEN={0};", authToken));
message.Headers.Add("Set-Cookie", string.Format("AUTH_TOKEN={0}", authToken));
message.Headers.Add("AUTH_TOKEN", authToken);
var result = await client.SendAsync(message);
result.EnsureSuccessStatusCode();
if (result.IsSuccessStatusCode)
{
var content = await result.Content.ReadAsStringAsync();
FeedItems= JsonConvert.DeserializeObject<List<Feed>>(content);
}
}
return FeedItems;
UPDATE
我试图用另一种解决方案,同样的结果。
var baseAddress = new Uri("http://app.*****.io");
var cookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
{
cookieContainer.Add(baseAddress, new Cookie("Cookie", string.Format("AUTH_TOKEN={0}", authToken)));
cookieContainer.Add(baseAddress, new Cookie("Set-Cookie", string.Format("AUTH_TOKEN={0}", authToken)));
var result = client.GetAsync("/api/v1/roles?api_key=sarasa").Result;
result.EnsureSuccessStatusCode();
if (result.IsSuccessStatusCode)
{
var content = await result.Content.ReadAsStringAsync();
RolesItems = JsonConvert.DeserializeObject<List<Role>>(content);
}
}
是否有替代品HttpClient
?
的可能的复制[如何在HttpClient的HttpRequestMessage上设置cookie(ht tp://stackoverflow.com/questions/12373738/how-do-i-set-a-cookie-on-httpclients-httprequestmessage) – SushiHangover
尝试:http://stackoverflow.com/a/13287224/4984832 – SushiHangover
@SushiHangover请参阅我更新的问题。我尝试了这个解决方案并没有工作,我会尝试使用另一个解决方案,看看它是否可以工作... – 4gus71n