【问题标题】:AngularJS pass requestVerificationToken to a serviceAngularJS 将 requestVerificationToken 传递给服务
【发布时间】:2013-08-08 04:33:28
【问题描述】:

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

【问题讨论】:

标签: angularjs angularjs-directive


【解决方案1】:

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

不要使用指令,只需使用 $http 服务文档中设置 HTTP 标头部分 http://docs.angularjs.org/api/ng.$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');
}]);

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

【讨论】:

    【解决方案2】:

    遗憾的是,最简单的方法是将jquery.js 包含在您的项目中angular.js 之前,然后这样做:

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

    【讨论】:

    • 嘿@Jason More,我只是想知道一种不使用JQuery的方法,它认为不推荐,我现在正在学习angularJS,所以我想从右脚开始开始!
    • 不幸的是,您混合了两件事 - 服务器端渲染(剃刀)和客户端模板(角度)。 jQuery 是它们之间的粘合剂。我会四处询问,但经过更多思考后,我相信这是正确的方法
    • @Pedro 您将不得不做一些事情才能将其从 DOM 中取出...您可以将 Jason 发布的代码添加到 Angular 服务/提供者/工厂,然后将其注入您的登录服务,但实际上这只是添加了一个抽象层,这可能会使测试更容易。
    • @Polaris878 是的,我会记住这一点,谢谢大家!我只需要尝试和想法,我会及时通知你!
    • 伙计们,这可能是什么情况?如果我修改 @Html.AntiForgeryToken() 呈现的方式并添加一个接受 ng-model 名称的重载,我认为这会改变整个画面吗?
    【解决方案3】:

    我遇到了同样的问题,我在自定义 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);
    }
    

    【讨论】:

      猜你喜欢
      • 2014-09-28
      • 1970-01-01
      • 2023-04-04
      • 2016-04-20
      • 2013-03-08
      • 2015-02-03
      • 2014-05-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多