2013-08-07 12 views
6

mi piacerebbe passare un RequestVerificationToken che è generato da un aiutante Razor MVC nel mio modulo di accesso a un servizio di AngularJS che ho fatto per gestire l'autenticazione della mia applicazioneAngularJS passano requestVerificationToken a un servizio

mia forma è la seguente:

<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> 

l'@ Html.AntiForgeryToken() rende in questo modo:

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

mio controller AngujarJs inietta successo LY mio "loginService" e mi possono inviare via posta il nome utente e la password per il servizio

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

    }; 
} 

il servizio:

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

La mia domanda è come posso leggere il token reso nella forma e passarlo al servizio e impostare un'intestazione con il token preso dal modulo di login, in quanto I as Know non è una buona pratica per manipolare il DOM e non so se avrò bisogno di creare una direttiva per eseguirlo compito quindi ogni suggerimento è benvenuto!

+0

Speranza avete guardato http://www.infoq.com/news/2012/10/anti-forgery-aspnet-json e http://stackoverflow.com/questions/15574486/angular-against -asp-net-webapi-implement-csrf-on-the-server – Chandermani

+0

sì, l'ho usato io per il servicestack per questo ho appena ottenuto tutto ciò che serve ho solo bisogno di sapere come passare il parametro al servizio! infatti penso di seguire un approccio molto simile come quello descritto qui http://stackoverflow.com/questions/15444781/angularjs-cant-find-xsrf-token-cookie –

+0

la mia risposta ti ha aiutato? –

risposta

14

Credo di aver trovato una soluzione abbastanza buona. Ho iniziato con i suggerimenti qui http://www.novanet.no/no/blog/olav-nybo/dates/2013/12/anti-forgery-tokens-using-mvc-web-api-and-angularjs/ ma il problema era che la direttiva viene eseguita dopo il controller. Quindi, se si desidera recuperare i dati iniziali nel controller, è stato molto difficile.

Invece di utilizzare la direttiva, utilizzare il metodo Module.run() come indicato nella documentazione del servizio $ http nella sezione Impostazione intestazioni HTTP http://docs.angularjs.org/api/ng.$http.

ho usato l'estensione HtmlHelper riferimento nel post del blog di cui sopra con l'elemento del corpo e poi la mia Module.run() si presenta così:

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

penso che abbia una soluzione piuttosto elegante.

+2

Questo è il modo corretto di gestire quel token IMO –

+1

grazie per l'aggiornamento! –

3

purtroppo, il modo più semplice è quello di includere jquery.js nel vostro progetto prima angular.js, quindi fare questo:

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

hey @Jason Altro, vorrei solo sapere un modo senza usare JQuery, supponendo che non sia raccomandato, sto imparando angularJS adesso, quindi mi piacerebbe iniziare col piede giusto sin dall'inizio! –

+1

Sfortunatamente si stanno mescolando due cose: rendering lato server (rasoio) e templatura lato client (angolare). jQuery è la colla tra di loro. Chiederò in giro ma dopo averci pensato di più, credo che questo sia il modo corretto –

+1

@Pedro Dovrai fare qualcosa per tirarlo fuori dal DOM ...potresti aggiungere il bit di codice che Jason ha inserito in un servizio/fornitore/fabbrica Angular e quindi iniettarlo nel tuo servizio di accesso, ma in realtà questo è solo aggiungere un livello di astrazione che potrebbe rendere più facile il test. – Polaris878

0

Ho avuto lo stesso problema e l'ho risolto creando un metodo AntiForgeryToken personalizzato in un HtmlHelper personalizzato.

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); 
} 
Problemi correlati