2016-06-24 16 views
0

Ich habe fest auf solche Probleme im Zusammenhang mit Cookies stecken.Set-Cookie in Antwort-Header nicht im Browser erstellt werden - Verwendung von http POST

Mein Szenario ist folgendes:

  • Ich habe meine Backend auf dem Server (localhst: 12456)
  • ich mein Eckige 2 App auf einem anderen Server ausgeführt haben (localhost: 5555)

Mein Backend ist nur eine ASP.NET-Anwendung und ich versuche, Benutzer von einem apiController zu authentifizieren. der api-Controller ist wie folgt:

[System.Web.Mvc.HttpPost] 
     public HttpResponseMessage HandleLogin([FromBody] LoginModel loginModel) 
     { 
      if (!String.IsNullOrEmpty(loginModel.Username) && !String.IsNullOrEmpty(loginModel.Password)) 
      { 

       if (Members.Login(loginModel.Username, loginModel.Password)) 
       { 
        var resp = Request.CreateResponse<UserAuthenticationModel>(
         HttpStatusCode.OK, 
         new UserAuthenticationModel() { IsAuthenticated = true} 
        ); 

        //create and set cookie in response 
        var cookie = new CookieHeaderValue("customCookie", "cookieVal"); 
        cookie.Expires = DateTimeOffset.Now.AddDays(1); 
        cookie.Domain = Request.RequestUri.Host; 
        cookie.Path = "/"; 
        resp.Headers.AddCookies(new CookieHeaderValue[] { cookie }); 

        return resp; 
       } 
      } 

      return Request.CreateResponse<UserAuthenticationModel>(
        new UserAuthenticationModel() { IsAuthenticated = false } 
      ); 
     } 

nun von meinem Winkel app, ich eine HTTP-Post nenne:

headers.append ('Access-Control-Allow-Credentials', true);

return this._http.post(this._globalVariables.BACKEND_API_HANDLE_LOGIN, loginModel, {headers: headers}) 
       .map((response : Response) => response); 

this._loginService.getLoginModel() .subscribe ( loginModel => this._signInPageModel = loginModel, error => console.log (Fehler) ); Nun, in meiner API-Controller-Methode (HandleLogin) habe ich einen Test-Cookie und einen anderen für FormsAuthentication und wenn Benutzer erfolgreich angemeldet und zurück zu meiner eckigen App, werden keine Cookies erstellt.

Nun können die Cookies sowie Post meiner Antwort-Header zu sehen:

enter image description here

ich es ziemlich verwirrend bin und freuen uns über jede Hilfe, um erfolgreich den Login-Prozess zu bekommen.

Vielen Dank im Voraus.

+0

Was ist Ihre Frage noch einmal? – AngJobs

+0

Haben Sie das Problem gefunden? –

Antwort

0

Ich verschwendete einen ganzen Tag auf das gleiche Problem. Was ich gefunden habe, ist, dass dies die wichtigen Bits sind:

1. Sie müssen die folgenden Header auf dem Server hinzufügen (durch Ihre Client-Host-Adresse ersetzen). Diese werden für CORS benötigt, die Sie benötigen, da Ihre zwei Sites unterschiedliche Portnummern verwenden.

Access-Control-Allow-Origin: http://localhost:5555 
Access-Control-Allow-Credentials: true 

Für WebAPI bedeutet dies das Recht, an der Spitze der WebApiConfig.Register folgende Platzierung:

var cors = new EnableCorsAttribute("http://localhost:5555", "*", "GET,POST"); 
cors.SupportsCredentials = true; 
config.EnableCors(cors); 

2. Seien Sie präzise darüber, wie Sie Ihre Cookies

Blick auf diese:

response.Headers.AddCookies(new CookieHeaderValue[] 
{ 
    new CookieHeaderValue("WorkingCookie", cookieValue) { Path="/" }, 
    new CookieHeaderValue("NotWorkingCookie", cookieValue) 
}); 

konnte ich nicht bekommen Ein CORS-Cookie, der ohne Angabe von Path funktioniert. Außerdem wird in Produktionsumgebungen unter this SO answer angegeben, dass Sie auch Domain angeben müssen. Ich bin noch nicht da, also notiere ich es erst jetzt.

3.Berücksichtigen Sie Back-End-Einschränkungen

Nicht wirklich ein Problem mit Web-API, die ich kenne, aber für PHP mehrere Set-Cookie Header funktionieren nicht gut. Ich konnte nur die letzte aufgelistete Liste auf dem Client erhalten.

4. Verwenden Sie withCredentials auf Ihrem HTTP-Anforderung *

Dies ist mein nehmen auf Ihren Anruf zuvor aufgeführt:

return this._http.post(this._globalVariables.BACKEND_API_HANDLE_LOGIN, 
    loginModel, {headers: headers, withCredentials: true}) 
    .map((response : Response) => response); 

Hinweis withCredentials als Teil der Optionen durchlaufen wird.

Dies war der fehlende Teil für Sie und ist absolut entscheidend. Die anderen Schritte dienen dazu sicherzustellen, dass die Cookies vom Server korrekt durchgesendet werden und vom Browser beibehalten werden, aber withCredentials regelt whether the browser will include its cookies in the request header.

Sie möchten sicherstellen, dass Sie eine neuere Version von Angular verwenden. selbst einige der RC-Versionen haben die Option withCredentials ignoriert und konnten daher nicht für CORS-Aufrufe wie diese verwendet werden.

Abschließender Hinweis Wenn Sie ein CORS-Authentifizierungssystem mit Cookies erstellen, gibt es zwei weitere Dinge zu kümmern:

  1. Mark Ihre Session-Cookie HttpOnly in Web-API, so kann es nicht sein, manipuliert durch JavaScript.
  2. Generieren und speichern Sie serverseitig einen Schlüssel, den Sie in einem (nicht HttpOnly) Cookie mit dem Namen XSRF-TOKEN zurückgeben. Vergleichen Sie bei jedem API-Aufruf diesen gespeicherten Wert mit dem Wert des Headers X-XSRF-TOKEN, den Angular zurückgibt. Dies wird zum Schutz vor CSRF attacks benötigt.