AngularJS将requestVerificationToken传递给服务

时间:2013-08-07 00:07:49

标签: angularjs angularjs-directive

我想将我的登录表单中由Razor MVC助手生成的RequestVerificationToken传递给我用来管理应用程序身份验证的AngularJS服务

我的表格如下:

<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控制器成功注入了我的“loginService”,我可以通过Post发送用户名和密码到服务

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和我不知道是否需要创建一个指令来执行该任务,所以欢迎任何建议!

3 个答案:

答案 0 :(得分:14)

我想我找到了一个很好的解决方案。我从这里的建议http://www.novanet.no/no/blog/olav-nybo/dates/2013/12/anti-forgery-tokens-using-mvc-web-api-and-angularjs/开始,但问题是指令是在控制器之后执行的。因此,如果您想要在控制器中检索初始数据,那将非常困难。

不要使用该指令,只需使用在设置HTTP标头部分http://docs.angularjs.org/api/ng.$http下的$ http服务文档中引用的Module.run()方法。

我使用上面博客文章中引用的HtmlHelper扩展名和body元素,然后我的Module.run()看起来像这样:

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

我认为这是一个非常优雅的解决方案。

答案 1 :(得分:3)

遗憾的是,最简单的方法是在jquery.js之前将angular.js包含到您的项目中,然后执行此操作:

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

答案 2 :(得分:0)

我有同样的问题,我解决了它在自定义HtmlHelper中制作自定义AntiForgeryToken方法。

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