Ich bin eine Xamarin Cross-Plattform-Mobile-App zu codieren. Der Server ist ein SpringMVC-Server, der JWT-Token zur Authentifizierung für jeden der Endpunkte/Webdienste verwendet. Also, im Grunde, wenn ich eine Anfrage an einen Webservice zum ersten Mal, bevor ich einen /authorize
POST-Endpunkt treffen muss senden meine E-Mail-Adresse und Passwort, die Endpoint-Antwort wird in der "Cookie"
Header ein Authenticaton Token, die als kommt. Sobald ich das Token bekommen habe, sende ich die Anfrage an den Endpunkt, sagen wir /feed
. Aber mein Problem ist, dass ich nicht herausfinden kann, wie man den "Cookie" Header in C# HttpClient
setzt. Ich habe alles versucht, aber die Endpoting reagiert nur mit dem Login-Bildschirm html anstatt der eigentlichen JSON-Antwort. Ich habe die gleichen Schritte in Postman und anderen REST-Clients versucht und es hat funktioniert. Es bedeutet also, dass ich etwas falsch mache. Hier ist mein Code:Authentifizierung von C# HttpClient gegen Spring Server JWT Tokens
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;
}
}
Als ich die Leitung var content = await response.Content.ReadAsStringAsync();
die Antwort erreichen ist ein HTML-String anstelle der tatsächlichen JSON-Antwort.
Ich versuchte mit mehreren anderen Schlüsselwerte für den Header, obwohl "Cookie"
derjenige ist, der auf Postman arbeitete.
Ich versuchte mit "Set-Cookie"
, "set-cookie"
, "Set-Cookie"
, die Überschrift als "AUTH_TOKEN"
setzen. Ich habe all diese Convinces an verschiedenen Stellen ausprobiert, wie zum Beispiel in der cookie
CookieContainer
, in der handler
CookieContainer
und in der client.DefaultRequestHeaders
.
Ich habe versucht, die handler.UseCookies = true; //Otherwise It'll not use the cookies container!!
Zeile ein- und auszuschalten.
Jede Hilfe ist willkommen!
UPDATE
Ich habe versucht, mit einem der vorgeschlagenen Lösungen, aber hat nicht funktioniert Ich habe versucht, entweder mit UseCookies in wahr und falsch.
//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
Ich habe versucht, mit der anderen Lösung gleichen Ergebnisse.
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);
}
}
Gibt es eine Alternative zu HttpClient
?
Mögliche Duplikat von [ Wie setze ich einen Cookie auf HttpRequestMessage von HttpClient] (ht tp: //stackoverflow.com/questions/12373738/how-doi-i-set-a-cookie-on-httpclients-httprequestmessage) – SushiHangover
Versuchen Sie: http://Stackoverflow.com/a/13287224/4984832 – SushiHangover
@SushiHangover Siehe meine aktualisierte Frage.Ich habe diese Lösung ausprobiert und nicht funktioniert, ich werde es mit der anderen Lösung versuchen und sehen, ob es funktioniert ... – 4gus71n