2013-08-07 4 views
6

Ich möchte eine RequestVerificationToken passieren, die von einem Razor MVC Helfer in meinem Login-Formular an einen AngularJS Dienst generiert wird, die ich getan habe, die Authentifizierung von meiner AnwendungAngularJS passieren requestVerificationToken zu einem Dienst

meine verwalten Form ist die folgende:

<div ng-model="loginRequest" > 
     <form ng-submit="submit()" ng-controller="loginCtrl"> 
      @Html.AntiForgeryToken() 

      <input id="username" ng-model="loginRequest.Username" type="text" name="text" /> 
      <input id="password" ng-model="loginRequest.Password" type="text" name="text" /> 
      <input type="submit" id="submit" value="Submit" /> 
      <br/> 
      isValid: {{loginRequest.isValid}} 
      <br/> 
      username: {{loginRequest.Username}} 
      <br/> 
      Password: {{loginRequest.Password}} 
     </form> 
    </div> 

das @ Html.AntiForgeryToken() auf diese Weise macht:

<input name="__RequestVerificationToken" type="hidden" value="AVzyqDKHSPjaY7L_GTpkasMAABRQRVRFUkFMSUVOV0FSRVxQZWRybwA1"> 

mein AngujarJs Controller erfolgreich injiziert ly meine „loginService“ und ich kann der Service

function loginCtrl($scope, loginService) { 
    $scope.submit = function() { 
     loginService.authenticate($scope.loginRequest,function(data) { 
      $scope.loginRequest.isValid = (data.User!=null); 
      //console.log(data); 
     }); 

    }; 
} 

über Pfosten den Benutzernamen und das Passwort an den Dienst senden:

angular.module('App.services', ['ngResource']). 
    factory('loginService', 
     function ($resource) { 
      return $resource('/Api/User/login', '', 
       { 
         authenticate: { 
         method: 'POST', 
         isArray: false, 
         headers: { 'X-XSRF-Token': '?????' } 
        } 
       }); 
     }); 

meine Frage ist, wie kann ich das Token lesen in der Form gemacht und Übergeben Sie es an den Dienst und setzen Sie eine Kopfzeile mit dem Token aus dem Login-Formular, so weit ich weiß, ist nicht eine gute Praxis, das DOM zu manipulieren, und ich weiß nicht, ob ich eine Direktive erstellen muss, um das auszuführen Aufgabe, damit irgendwelche Vorschläge willkommen sind!

+0

Hoffnung haben Sie bei http://www.infoq.com/news/2012/10/anti-forgery-aspnet-json sah und http://stackoverflow.com/questions/15574486/angular-against -asp-net-webapi-implement-csrf-auf-dem-server – Chandermani

+0

ja ich tat, ich benutze servicestack für es Ich habe gerade alles abgedeckt Ich muss nur wissen, wie man den Parameter an den Service übergeben! in der Tat denke ich, dass ich einem sehr ähnlichen Ansatz wie dem hier beschriebenen folgen http://stackoverflow.com/questions/15444781/angularjs-cant-find-xsrf-token-cookie –

+0

hat meine Antwort Ihnen überhaupt geholfen? –

Antwort

14

Ich glaube, ich eine ziemlich gute Lösung gefunden haben. Ich begann mit den Vorschlägen hier http://www.novanet.no/no/blog/olav-nybo/dates/2013/12/anti-forgery-tokens-using-mvc-web-api-and-angularjs/ aber das Problem war, dass die Direktive nach dem Controller ausgeführt wird. Wenn Sie also Anfangsdaten im Controller abrufen wollten, war das sehr schwierig.

Anstatt die Direktive zu verwenden, verwenden Sie einfach die Module.run() -Methode, wie in der $ http-Servicedokumentation unter dem Abschnitt HTTP-Header definieren http://docs.angularjs.org/api/ng.$http beschrieben.

verwendete ich die Htmlhelper-Erweiterung im Blog-Eintrag verwiesen oben mit dem Körperelement und dann meine Module.run() sieht wie folgt aus:

myModule.run(['$http', function($http) { 
    $http.defaults.headers.common['RequestVerificationToken'] = angular.element("body").attr('ncg-request-verification-token'); 
}]); 

Ich denke, es ist eine ziemlich elegante Lösung macht.

+2

Dies ist der richtige Weg, um dieses Token IMO –

+1

Dank für das Update zu behandeln! –

3

traurig, der einfachste Weg, jquery.js in Ihr Projekt vor angular.js enthalten ist, dann dies tun:

headers: { 'X-XSRF-Token': angular.element('input[name="__RequestVerificationToken"]') } 
+0

hey @Jason More, ich würde einfach gerne einen Weg kennen ohne JQuery zu benutzen. Ich vermute, dass das nicht empfehlenswert ist. Ich lerne gerade angularJS, also würde ich gerne mit dem rechten Fuß von Anfang an anfangen! –

+1

Leider mischen Sie zwei Dinge - serverseitiges Rendering (Rasierer) und clientseitige Templating (eckig). jQuery ist der Kleber zwischen ihnen. Ich werde fragen, aber nachdem ich darüber nachgedacht habe, glaube ich, dass dies der richtige Weg ist. –

+1

@Pedro Sie müssen etwas tun, um es aus dem DOM zu bekommen ...Sie könnten das Code-Bit hinzufügen, das Jason in einem Angular-Dienst/Provider/Factory gepostet hat, und es dann in Ihren Login-Dienst einfügen, aber das ist nur eine Ebene der Abstraktion, die den Test einfacher macht. – Polaris878

0

Ich hatte das gleiche Problem und löste es, indem ich eine benutzerdefinierte AntiForgeryToken-Methode in einem benutzerdefinierten HtmlHelper machte.

public static IHtmlString AngularAntiForgeryToken(this HtmlHelper html, string ngModelName = "AntiForgeryToken") 
{ 
    MvcHtmlString antiForgery = html.AntiForgeryToken(); 
    string antiForgeryString = antiForgery.ToString(); 
    Regex regex = new Regex(string.Format("value=[\"|']([a-zA-Z0-9+=/\\-_]+)[\"|']", ngModelName)); 
    Match match = regex.Match(antiForgeryString); 
    string antiForgeryToken = string.Empty; 
    if (match.Success) 
     antiForgeryToken = match.Groups[1].ToString(); 

    string result = antiForgeryString.Replace("<input", string.Format("<input ng-model=\"{0}\" ng-init=\"{0} = '{1}'\"", ngModelName, antiForgeryToken)); 

    return new HtmlString(result); 
} 
Verwandte Themen