2013-08-07 57 views
6

我想通過它由剃刀MVC幫手產生在我的登錄表單,我已經做了我的管理應用AngularJS傳遞requestVerificationToken到服務

認證的AngularJS服務RequestVerificationToken我格式如下:

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

這樣的@ Html.AntiForgeryToken()呈現:

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

我AngujarJs控制器注入成功LY我的「login服務」,我可以通過郵寄的用戶名和密碼發送到服務

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

    }; 
} 

服務:

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

我的問題是我怎麼能閱讀的形式呈現的令牌和將它傳遞給服務,並使用從登錄表單中獲取的令牌設置標題,儘管我不知道如何操作DOM,但我不知道是否需要創建指令來執行該操作任務,所以任何建議,歡迎!

+0

希望你已經看過http://www.infoq.com/news/2012/10/anti-forgery-aspnet-json和http://stackoverflow.com/questions/15574486/angular-against -Asp淨的WebAPI-CSRF最服務器上實施的, – Chandermani

+0

是我沒有,I'm使用servicestack它我剛剛得到的一切覆蓋我只需要知道如何將參數傳遞給服務!其實我覺得我下面喜歡這裏http://stackoverflow.com/questions/15444781/angularjs-cant-find-xsrf-token-cookie描述 –

+0

的一個非常類似的方法做了我的回答幫助你呢? –

回答

14

我想我已經找到了一個不錯的解決方案。我開始在這裏的建議http://www.novanet.no/no/blog/olav-nybo/dates/2013/12/anti-forgery-tokens-using-mvc-web-api-and-angularjs/但問題是該指令在控制器後執行。所以如果你想在控制器中檢索初始數據,這是非常困難的。

而不是使用的指令只使用Module.run()方法作爲設置HTTP頭部分http://docs.angularjs.org/api/ng.$http下的$ HTTP服務文檔中引用。

我使用的HtmlHelper擴展在博客中引用上面body元素,然後我Module.run()看起來是這樣的:

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

我認爲它使一個相當優雅的解決方案。

+2

這是正確的方式來處理該令牌IMO –

+1

感謝您的更新! –

3

可悲的是,最簡單的方法是將包括jquery.jsangular.js之前你的項目,那麼這樣做:

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

哎@Jason更多,我只是想知道,不使用JQuery的方式,推測不推薦,我正在學習angularJS所以我現在想開始從一開始的右腳! –

+1

不幸的是,你正在混合兩件事 - 服務器端渲染(剃鬚刀)和客戶端模板(角)。 jQuery是它們之間的粘合劑。我會問左右,但思考更加之後,我相信這是正確的方式 –

+1

@Pedro你必須做一些事情來把它弄出來的DOM ...您可以將Jason發佈的代碼添加到Angular服務/提供程序/工廠中,然後將其注入到您的登錄服務中,但實際上這只是添加了一層可能使其更容易測試的抽象。 – Polaris878

0

我有這個同樣的問題,我解決它製作一個定製AntiForgeryToken方法在定製的HtmlHelper。

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