• 开始使用AngularJS和ASP。期待已久的第三部分


    文章系列: 第一部分第二部分第三部分(本文) 介绍 早在8月份我就写了本系列的第一部分和第二部分,从那以后我就一直打算写第三部分,但是一直被这个和那个弄得跑题了(松鼠!) 在第三部分中我们要做的事情 用ASP构建RESTful API的基础。Net Web API,带有身份验证,角色等,然后创建一个新的Angular应用,它连接到这个API 源代码 本文附带的源代码可以在这里找到。 基于rest的API 好的,让我们开始我们的RESTful API。在Visual Studio中选择New Project…=比;Web =比;ASP。Net Web Application(命名为Awesome Angular Web App 2.0) =>Web API。在个人用户帐户上保留身份验证并单击OK。 现在我想要你安装三个应用程序,如果你还没有: 邮差node . js提琴手 一旦你安装了邮差,浏览到以下网址在Chrome: chrome扩展:/ / fdmmgilgnpjigdojojpjoooidkmcomcm / index . html 如果你熟悉ASP。净MVC Web API在某些方面会有一个相对较小的学习曲线,因为它是基于相同的技术,也是基于MVC的等,但在其他方面更大的学习曲线(从的角度需要了解HTTP RESTful API是什么和如何架构师等。这不是那篇文章,但我建议你读一本这方面的好书。) 按F5(或任何调试键)启动我们的Web API项目。你应该看到这样的东西: 点击API。当我们构建一个API时,这个页面会自动更新有关所有端点的信息以及相关的HTTP请求类型。点击这里的一个方法会给你关于那个特定端点的详细信息,包括参数等等。在某种程度上,它本质上是自我记录的。 网站还在运行,邮递员跑吧。我们将创建一个用户和登录。Web API使用基于令牌的身份验证,而不是基于cookie的身份验证。其工作方式非常简单,如果您使用有效的用户名和密码登录,API将返回一个令牌,以及关于该令牌有效持续时间的信息。您将此令牌作为头添加到以下所有HTTP请求中,然后服务器就知道您是谁。 就像普通的ASP。Net身份验证,您可以使用[Authenticate]属性限制对控制器或方法的访问。您还可以创建角色,并允许不同的用户根据他们的角色访问API的不同部分。 让我们创建一个用户。查看URL以确定您的API正在运行的端口(它运行localhost,冒号,端口号),然后将以下内容放入邮差的URL栏,用您的端口替换8888: http://localhost:8888/api/Account/register 在下面的栏中,点击raw并粘贴以下JSON到下面的文本框(不要担心,AngularJS的东西来了,但我们需要先完成这个): 隐藏,复制Code

    {
      "Email": "email@email.com",
      "Password": "Password1!",
      "ConfirmPassword": "Password1!"
    }

    我们还需要将此请求的内容类型设置为json,因此单击header并添加名为content - type的新头部,其值为application/json。最后,在下拉列表中将请求类型更改为POST。 邮递员的长相应该是这样的: 点击发送。这将花费几秒钟的时间,因为ASP。Net正在后台创建数据库,但一旦它完成了,你应该得到一个200 OK的响应,像这样: 如果你查看fiddler,你应该也能找到这个请求。在这里查看不同的标签/按钮,探索请求的细节: 现在我们已经创建了一个用户,让我们继续登录。更改URL为: http://localhost:8888/token 这仍然是一篇文章,但是现在我们想将数据模式更改为x-www-form- urlencodes,所以单击这个按钮。添加以下字段: grant_type: password username: email@email.com(或您注册的其他地址)password: Password1!(或者你注册时设置的密码) 邮递员现在应该是这个样子: 点击发送,类似于以下内容将返回: 隐藏,复制Code

    {
        "access_token": "R-AejC88wImTKUulwlZBRsR620zXuHcrjV26UGObVjl5s9aqJIhs2hzt60CdLhL0hXNR-kyLTgrTfiMDV4JZJsmC1jV3MQHKcScsW6lYAMz1kegSyQiSfRHVj8W1E76x9uiHYJVIWhwA_RH7GkTn3K_Z0ugV_0qsSd1cWZ5qpqRedrS1vbHNIr7PR-FvAcKGA5c0S7ffadD8TP6N8OX8AyEg2t5rxppAeT2AlqlY3G5HdJqDkPgXQx5pL_xXRWkQCuOhIgUCm-6TDAksNf-EJ7HzPKD7nl7KU8Pd66rQO56p_vtq6eOO9OtgAmN8FviR-gNKGHCsz4udPrAKTExF_Ht4hBpbLoiGIXIbVUpzTeB-RMZUMMcRgByo4tCELjd41pV0mjaXHS6s7mTuwlgGmxiAU5AoYgNTXVOe9YegZMvjW_lAIUw0YlZ0m7RAiPOTTDlRzmV1ntm3YGvAN9h9_m027twqfGz5YsHsbh3RYW8",
        "token_type": "bearer",
        "expires_in": 1209599,
        "userName": "email@email.com",
        ".issued": "Sun, 16 Nov 2014 22:55:45 GMT",
        ".expires": "Sun, 30 Nov 2014 22:55:45 GMT"
    }

    RESTful API和Web API,非常有限的入门 当我们创建Web API项目时,它为我们创建了一个名为ValuesController的控制器,其中包含五个方法: Get(重载带有参数的版本)发布put delete 控制器的名称对应于URL(如在ASP中)。方法的名称对应于请求的HTTP谓词。因此,如果您想为HTTP Get请求编写端点,您可以创建一个名为Get的方法。 如何构建一个RESTful API超出了本文的范围,但通常您使用以下方法: Get request to Get something post to do something(执行一个动作)put to put something somewhere(如在数据库中)delete to delete 你总是响应HTTP请求与状态码指示的结果。当我们注册和登录时,我们得到一个2每次00响应。您可以在Postman中随意处理这些请求(所有的东西都保存在历史中),提供不同的值,删除/添加值等等,在不同的场景中看到不同的状态代码返回。例如,如果您在登录时提供了错误的密码,您会得到400个错误请求的响应。 维基百科的页面很好地分解了各种状态码。一旦你读了这篇文章,我建议你到这里来阅读关于7xx系列的文章。你将在维基百科文章之后需要它。 所有的HTTP请求都可以包含header,而不管它们的HTTP动词(Get, Post等)是什么,有些还可以包含body,而有些则不能。例如,Post可以包含body,但是Get不能。在Web API中,这个主体是使用stronly类型的c#对象构建的,并从方法返回。 让我们尝试调用这个values控制器的Get方法。在邮差,改变HTTP动作类型,以获取在下拉列表和URL如下: http://localhost:8888/api/values 现在将内容类型保留为application/json。邮递员应该是这样的: 点击发送,我们会收到401未经授权的回复。这是因为Values控制器是由[Authorize]属性保护的!哎! 在Postman中,添加一个名为Authorization的新标题,其值为holder,后面是空格,后面是我们之前取回的令牌。邮递员现在应该是这样的: 再次点击发送,成功!我们从API得到以下JSON: 隐藏,复制Code

    [
        "value1",
        "value2"
    ]

    玩弄Postman调用values控制器中的每个方法,并改变方法以返回不同类型的对象。您将能够看到所有这些行动在邮差也,以及每个请求的详细信息。很酷,不是吗? 这应该是一篇关于角绳的文章,但我们还没有做任何角绳!去找角兔吧! 好吧,好吧。这一次,我们不打算创建一个ASP。Net MVC应用程序来容纳我们的网站,我们将创建一切使用纯旧的CSS, HTML和Javascript和一点Node.JS。 我之前要求您安装Node.JS。因为当前版本的Node有错误。JS,你还需要在以下位置创建一个名为npm的目录: C:Users{{您的用户名}} AppData 漫游 这个问题可能会在您阅读本文时得到解决,如果是这样的话,请忽略(也许可以留下评论)。 为你的网站创建一个目录,用你最喜欢的文本编辑器(我用的是Atom)创建一个index.html文件,包含以下内容: 隐藏,复制Code

    <!DOCTYPE html>
    <html>
    
    <head>
    <title>Awesome Angular Web App 2.0</title>
    </head>
    
    <body>
    Hello Again!
    </body>
    
    </html>

    现在打开Node.js命令提示符,运行以下命令: 安装http-server -g 这将安装一个内置在Javascript中的轻量级web服务器,叫做http-server,我们可以在它上面运行Angular应用。g旗代表全球。这意味着服务器被安装到你的PC上,并且可以在任何地方运行。如果忽略了这个,服务器将被安装到您当前所在的目录中。 现在导航到存放网站的目录,并运行http-server。你的窗口应该是这样的: 在浏览器中,浏览到http://localhost:8080/。 这不是很棒吗? 添加一个子目录Scripts和一个子目录Styles。我们已经在第一部分和第二部分讨论过了这些内容,所以我不打算在这里解释太多,只是复制粘贴我创建的每个文件的内容: index . html 隐藏,复制Code

    <!DOCTYPE html>
    <html>
    
    <head>
    <title>Awesome Angular Web App 2.0</title>
    </head>
    
    <body ng-app="AwesomeAngularWebApp" ng-controller="BaseController">
    {{helloAgain}}
    
    <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.0/angular.min.js"></script>
    
    <script src="/Scripts/Controllers/BaseController.js"></script>
    <script src="/Scripts/AwesomeAngularWebApp.js"></script>
    </body>
    
    </html>

    脚本/ AwesomeAngularWebApp.js 隐藏,复制Code

    var AwesomeAngularWebApp = angular.module('AwesomeAngularWebApp', []);
    AwesomeAngularWebApp.controller('BaseController', BaseController);

    脚本/控制器/ BaseController.js 隐藏,复制Code

    var BaseController = function($scope){
        $scope.helloAgain = 'Hello Angular 1.3!';
    }
    BaseController.$inject = ['$scope'];

    http://localhost:8080/现在应该如下所示: 当身份验证令牌从API返回时,我们需要一个存储它的地方。我们可以在服务中这样做。AngularJS中的服务是单例的,在应用程序启动时创建一个实例,你可以通过依赖注入来传递这个实例。它们是存储应用程序的多个部分所需的值的好地方。 脚本/服务/ SessionService.js 隐藏,复制Code

    var AuthenticationService = function(){
        this.token = undefined;
    }

    脚本/ AwesomeAngularWebApp.js 隐藏,复制Code

    var AwesomeAngularWebApp = angular.module('AwesomeAngularWebApp', []);
    AwesomeAngularWebApp.controller('BaseController', BaseController);
    AwesomeAngularWebApp.service('SessionService', SessionService);

    让我们创建工厂来登录和注册: 脚本/工厂/ LoginFactory.js 隐藏,收缩,复制Code

    var LoginFactory = function($http, $q, SessionService){
        return function(username, password){    
            var result = $q.defer();
        
            var params = {grant_type: "password", userName: username, password: password};
        
            $http({
                method: 'POST',
                url: SessionService.apiUrl + '/token',
                transformRequest: function(obj) {
                    var str = [];
                    for(var p in obj)
                    str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
                    return str.join("&");
                },
                data: params,
                headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8;'}
            })
            .success(function(response){
                result.resolve(response);
            })
            .error(function(response){
                result.reject(response);
            });
            
            return result.promise; 
        }
    }
    
    LoginFactory.$inject = ['$http', '$q', 'SessionService'];

    脚本/工厂/ RegisterFactory.js 隐藏,复制Code

    var RegisterFactory = function($http, $q, SessionService){
        return function(email, password, confirmPassword){    
            var result = $q.defer();
        
            $http({
                method: 'POST',
                url: SessionService.apiUrl + '/api/Account/register',
                data: {Email: email, Password: password, ConfirmPassword: confirmPassword},
                headers: {'Content-Type': 'application/json'}
            })
            .success(function(response){
                result.resolve(response);
            })
            .error(function(response){
                result.reject(response);
            });
            
            return result.promise; 
        }
    
    }
    
    RegisterFactory.$inject = ['$http', '$q', 'SessionService'];

    脚本/ AwesomeAngularWebApp.js 隐藏,复制Code

    var AwesomeAngularWebApp = angular.module('AwesomeAngularWebApp', []);
    AwesomeAngularWebApp.controller('BaseController', BaseController);
    AwesomeAngularWebApp.service('SessionService', SessionService);
    AwesomeAngularWebApp.factory('LoginFactory', LoginFactory);
    AwesomeAngularWebApp.factory('RegisterFactory', RegisterFactory);

    现在我要为登录和注册视图创建一个控制器(我们马上就会做): 脚本/控制器/ LoginController.js 隐藏,复制Code

    var LoginController = function($scope, $location, LoginFactory, SessionService){
        $scope.loginForm = {
            username: undefined,
            password: undefined, 
            errorMessage: undefined
        };
        
        $scope.login = function(){
            LoginFactory($scope.loginForm.username, $scope.loginForm.password)
            .then(function(response){
                SessionService.token = response.access_token;
                $location.path('/');
            }, function(response){
                $scope.loginForm.errorMessage = response.error_description;
            });
        }
    }
    LoginController.$inject = ['$scope', '$location', 'LoginFactory', 'SessionService'];

    脚本/控制器/ RegisterController.js 隐藏,复制Code

    var RegisterController = function($scope, LoginFactory, RegisterFactory, SessionService){
        $scope.registerForm = {
            username: undefined,
            password: undefined, 
            confirmPassword: undefined,
            errorMessage: undefined
        };
        
        $scope.register = function(){
            RegisterFactory($scope.registerForm.username, $scope.registerForm.password, $scope.registerForm.confirmPassword)
            .then(function(){
                LoginFactory($scope.registerForm.username, $scope.registerForm.password)
                .then(function(response){
                    SessionService.token = response.access_token;
                }, function(response){
                    $scope.registerForm.errorMessage = response;
                });
            }, function(response){
                $scope.registerForm.errorMessage = response;
            });
        }
    }
    RegisterController.$inject = ['$scope', 'LoginFactory', 'RegisterFactory', 'SessionService'];

    脚本/ AwesomeAngularWebApp.js 隐藏,复制Code

    var AwesomeAngularWebApp = angular.module('AwesomeAngularWebApp', []);
    AwesomeAngularWebApp.controller('BaseController', BaseController);
    AwesomeAngularWebApp.controller('LoginController', LoginController);
    AwesomeAngularWebApp.controller('RegisterController', RegisterController);
    AwesomeAngularWebApp.service('SessionService', SessionService);
    AwesomeAngularWebApp.factory('LoginFactory', LoginFactory);
    AwesomeAngularWebApp.factory('RegisterFactory', RegisterFactory);

    这些控制器的视图,带有更新的路由代码: 视图/ Login.html 隐藏,复制Code

    <form role="form" ng-submit="login()">
      <div class="form-group">
        <label for="emailAddress">Email address</label>
        <input type="email" class="form-control" id="emailAddress" placeholder="Enter email" ng-model="loginForm.username">
      </div>
      <div class="form-group">
        <label for="password">Password</label>
        <input type="password" class="form-control" id="password" placeholder="Password" ng-model="loginForm.password">
      </div>
        <p class="help-block" ng-if="loginForm.errorMessage">{{loginForm.errorMessage}}</p>
      </div>
      <button type="submit" class="btn btn-default">Login</button>
    </form>

    视图/ Register.html 隐藏,复制Code

    <form role="form" ng-submit="register()">
      <div class="form-group">
        <label for="emailAddress">Email address</label>
        <input type="email" class="form-control" id="emailAddress" placeholder="Enter email" ng-model="registerForm.username">
      </div>
      <div class="form-group">
        <label for="password">Password</label>
        <input type="password" class="form-control" id="password" placeholder="Password" ng-model="registerForm.password">
      </div>
      <div class="form-group">
        <label for="password">Confirm Password</label>
        <input type="password" class="form-control" id="password" placeholder="Confirm Password" ng-model="registerForm.confirmPassword">
      </div>
        <p class="help-block" ng-if="registerForm.errorMessage">{{registerForm.errorMessage}}</p>
      </div>
      <button type="submit" class="btn btn-default">Register</button>
    </form>

    脚本/ AwesomeAngularWebApp.js隐藏,复制Code

    var AwesomeAngularWebApp = angular.module('AwesomeAngularWebApp', ['ngRoute']);
    AwesomeAngularWebApp.controller('BaseController', BaseController);
    AwesomeAngularWebApp.controller('LoginController', LoginController);
    AwesomeAngularWebApp.controller('RegisterController', RegisterController);
    AwesomeAngularWebApp.service('SessionService', SessionService);
    AwesomeAngularWebApp.factory('LoginFactory', LoginFactory);
    AwesomeAngularWebApp.factory('RegisterFactory', RegisterFactory);
    
    var ConfigFunction = function($routeProvider) {
      $routeProvider
       .when('/login', {
        templateUrl: 'views/login.html',
        controller: 'LoginController'
      })
      .when('/register', {
        templateUrl: 'views/register.html',
        controller: 'RegisterController'
      });
    };
    ConfigFunction.$inject = ['$routeProvider'];
    AwesomeAngularWebApp.config(ConfigFunction);

    index . html 隐藏,收缩,复制Code

    <!DOCTYPE html>
    <html>
    
    <head>
    <title>Awesome Angular Web App 2.0</title>
    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.1/css/bootstrap.min.css">
    </head>
    
    <body ng-app="AwesomeAngularWebApp" ng-controller="BaseController">
    {{helloAgain}}
    
    <a href="/#/login" ng-if="!loggedIn()">Login</a>
    <a href="/#/register" ng-if="!loggedIn()">Register</a>
    
    <span class="label label-success" ng-if="loggedIn()">Logged In</span>
    
    <div ng-view></div>
    
    <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.0/angular.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.0/angular-route.min.js"></script>
    
    <script src="/Scripts/Controllers/BaseController.js"></script>
    <script src="/Scripts/Controllers/LoginController.js"></script>
    <script src="/Scripts/Controllers/RegisterController.js"></script>
    <script src="/Scripts/Services/SessionService.js"></script>
    <script src="/Scripts/Factories/LoginFactory.js"></script>
    <script src="/Scripts/Factories/RegisterFactory.js"></script>
    <script src="/Scripts/AwesomeAngularWebApp.js"></script>
    </body>
    
    </html>

    脚本/ BaseController.js 隐藏,复制Code

    var BaseController = function($scope, SessionService){
        $scope.helloAgain = 'Hello Angular 1.3!';
        
        $scope.loggedIn = function(){
            return SessionService.token !== undefined;
        }
    }
    BaseController.$inject = ['$scope', 'SessionService'];

    好,让我们导航回http://localhost:8080/,确保所有东西都连接好了。您应该能够浏览到登录和注册视图。检查你的浏览器控制台,如果有错误,你可能漏掉了一个步骤(或者我搞砸了,如果是这样,请在评论中告诉我) 让我们尝试登录 为了让你不用向上滚动,下面是我们之前创建的用户的用户名和密码(除非你修改了它们,否则向上滚动是没有用的): 用户名:email@email.com密码:Password1! 让我们浏览到登录表单,并尝试登录。哦不: 我们的API在一个服务器上,而我们的网站在另一个服务器上,所以登录请求被浏览器出于安全原因阻止。我们可以用CORS解决这个问题。 回到Visual Studio,从View =>打开nuget包管理器控制台其他窗口=比;包管理器控制台。运行以下命令: 隐藏,复制Code

    Install-Package Microsoft.Owin.Cors

    在启动。cs,修改配置,使其包含以下内容: 隐藏,复制Code

            public void Configuration(IAppBuilder app)
            {
                app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
                ConfigureAuth(app);
            }

    让我们试着再次登录,首先使用一个故意不正确的用户名/密码组合: 很好,我们从服务器取回400,并在屏幕上显示错误消息。现在让我们正确登录: 史诗!我们回到主页,我们的令牌存储在服务中,登录和注册链接消失了。 现在我们将编写一个工厂来从API中的ValuesController类中获取值: 脚本/工厂/ GetValuesFactory.js 隐藏,复制Code

    var GetValuesFactory = function($http, $q, SessionService){
        return function(){    
            var result = $q.defer();
        
            $http({
                method: 'GET',
                url: SessionService.apiUrl + '/api/Values',
                headers: {'Content-Type': 'application/json', 'Authorization': 'Bearer ' + SessionService.token}
            })
            .success(function(response){
                result.resolve(response);
            })
            .error(function(response){
                result.reject(response);
            });
            
            return result.promise; 
        }
    }
    
    GetValuesFactory.$inject = ['$http', '$q', 'SessionService'];

    我们马上要创建的视图控制器: 脚本/控制器/ ValuesController.js 隐藏,复制Code

    var ValuesController = function($scope, GetValuesFactory, SessionService){
        $scope.values = [];
        $scope.error = {
            message: undefined
        };
        
        $scope.getValues = function(){
            GetValuesFactory()
            .then(function(response){
                $scope.values = response;
            }, function(response){
                $scope.error.message = response.Message;
            });
        }
    }
    ValuesController.$inject = ['$scope', 'GetValuesFactory', 'SessionService'];

    一个视图: 视图/ values.html 隐藏,复制Code

    <button ng-click="getValues()">Get Values</button>
    
    <ul class="nav nav-pills" ng-if="values.length > 0">
        <li ng-repeat="value in values">{{value}}<li>
    </ul>
    
    <p class="help-block" ng-if="error.message">{{error.message}}</p>

    更新的路径和新jazz的注册: 脚本/ AwesomeAngularWebApp.js 隐藏,收缩,复制Code

    var AwesomeAngularWebApp = angular.module('AwesomeAngularWebApp', ['ngRoute']);
    AwesomeAngularWebApp.controller('BaseController', BaseController);
    AwesomeAngularWebApp.controller('LoginController', LoginController);
    AwesomeAngularWebApp.controller('RegisterController', RegisterController);
    AwesomeAngularWebApp.controller('ValuesController', ValuesController);
    AwesomeAngularWebApp.service('SessionService', SessionService);
    AwesomeAngularWebApp.factory('LoginFactory', LoginFactory);
    AwesomeAngularWebApp.factory('RegisterFactory', RegisterFactory);
    AwesomeAngularWebApp.factory('GetValuesFactory', GetValuesFactory);
    
    var ConfigFunction = function($routeProvider) {
      $routeProvider
       .when('/login', {
        templateUrl: 'views/login.html',
        controller: 'LoginController'
      })
      .when('/register', {
        templateUrl: 'views/register.html',
        controller: 'RegisterController'
      })
      .when('/values', {
        templateUrl: 'views/values.html',
        controller: 'ValuesController'
      });
    };
    ConfigFunction.$inject = ['$routeProvider'];
    AwesomeAngularWebApp.config(ConfigFunction);

    新控制器/工厂的链接和脚本标签: 隐藏,收缩,复制Code

    <!DOCTYPE html>
    <html>
    
    <head>
    <title>Awesome Angular Web App 2.0</title>
    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.1/css/bootstrap.min.css">
    </head>
    
    <body ng-app="AwesomeAngularWebApp" ng-controller="BaseController">
    {{helloAgain}}
    
    <a href="/#/login" ng-if="!loggedIn()">Login</a>
    <a href="/#/register" ng-if="!loggedIn()">Register</a>
    <a href="/#/values">Values</a>
    
    <span class="label label-success" ng-if="loggedIn()">Logged In</span>
    
    <div ng-view></div>
    
    <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.0/angular.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.0/angular-route.min.js"></script>
    
    <script src="/Scripts/Controllers/BaseController.js"></script>
    <script src="/Scripts/Controllers/LoginController.js"></script>
    <script src="/Scripts/Controllers/RegisterController.js"></script>
    <script src="/Scripts/Controllers/ValuesController.js"></script>
    <script src="/Scripts/Services/SessionService.js"></script>
    <script src="/Scripts/Factories/LoginFactory.js"></script>
    <script src="/Scripts/Factories/RegisterFactory.js"></script>
    <script src="/Scripts/Factories/GetValuesFactory.js"></script>
    <script src="/Scripts/AwesomeAngularWebApp.js"></script>
    </body>
    
    </html>

    好,把所有东西都点燃。首先,导航到我们的新值视图并点击按钮。Web API返回一个显示在屏幕上的401(未经授权)http错误。登录并再次按下按钮,一切工作正常。 别忘了我 目前,如果您登录,然后刷新页面,您将被踢出并需要重新进行身份验证。我们可以通过使用AngularJS的ng-cookie模块将令牌存储在cookie中来解决这个问题。更新index.html,像这样从Cloudflare下拉这个(添加到角路径标签后): 隐藏,复制Code

    <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.0/angular-cookies.min.js"></script>

    更新AwesomeAngularWebApp.js在我们的app中注册这个模块: 隐藏,复制Code

    var AwesomeAngularWebApp = angular.module('AwesomeAngularWebApp', ['ngRoute', 'ngCookies']);

    更新SessionService以获取令牌并将其存储在cookie中: 隐藏,复制Code

    var SessionService = function($cookies){
        this.token = undefined;
        
        this.getToken = function(){
            if(!$cookies.awesomeAngularWebAppToken){
                if(!this.token){
                    return undefined;
                }
                this.setToken(this.token);            
            }
            return $cookies.awesomeAngularWebAppToken;
        }
        
        this.setToken = function(token){
            this.token = token;
            $cookies.awesomeAngularWebAppToken = token;
        }
        
        this.apiUrl = 'http://localhost:5586';
    }
    
    SessionService.$inject = ['$cookies'];

    LoginController和RegisterController, BaseController和GetValuesFactory调用新的getter和setter方法: 脚本/控制器/ LoginController.js 隐藏,复制Code

    var LoginController = function($scope, $location, LoginFactory, SessionService){
        $scope.loginForm = {
            username: undefined,
            password: undefined, 
            errorMessage: undefined
        };
        
        $scope.login = function(){
            LoginFactory($scope.loginForm.username, $scope.loginForm.password)
            .then(function(response){
                SessionService.setToken(response.access_token);
                $location.path('/');
            }, function(response){
                $scope.loginForm.errorMessage = response.error_description;
            });
        }
    }
    LoginController.$inject = ['$scope', '$location', 'LoginFactory', 'SessionService'];

    脚本/控制器/ RegisterController.js 隐藏,复制Code

    var RegisterController = function($scope, LoginFactory, RegisterFactory, SessionService){
        $scope.registerForm = {
            username: undefined,
            password: undefined, 
            confirmPassword: undefined,
            errorMessage: undefined
        };
        
        $scope.register = function(){
            RegisterFactory($scope.registerForm.username, $scope.registerForm.password, $scope.registerForm.confirmPassword)
            .then(function(){
                LoginFactory($scope.registerForm.username, $scope.registerForm.password)
                .then(function(response){
                    SessionService.setToken(response.access_token);
                }, function(response){
                    $scope.loginForm.errorMessage = response;
                });
            }, function(response){
                $scope.registerForm.errorMessage = response;
            });
        }
    }
    RegisterController.$inject = ['$scope', 'LoginFactory', 'RegisterFactory', 'SessionService'];

    脚本/控制器/ BaseController.js 隐藏,复制Code

    var BaseController = function($scope, SessionService){
        $scope.helloAgain = 'Hello Angular 1.3!';
        
        $scope.loggedIn = function(){
            return SessionService.getToken() !== undefined;
        }
    }
    BaseController.$inject = ['$scope', 'SessionService'];

    脚本/工厂/ GetValuesFactory.js 隐藏,复制Code

    var GetValuesFactory = function($http, $q, SessionService){
        return function(){    
            var result = $q.defer();
        
            $http({
                method: 'GET',
                url: SessionService.apiUrl + '/api/Values',
                headers: {'Content-Type': 'application/json', 'Authorization': 'Bearer ' + SessionService.getToken()}
            })
            .success(function(response){
                result.resolve(response);
            })
            .error(function(response){
                result.reject(response);
            });
            
            return result.promise; 
        }
    }
    
    GetValuesFactory.$inject = ['$http', '$q', 'SessionService'];

    现在,当您登录并点击刷新,您仍然登录!Wohoo ! 角色 如前所述,不同的用户可以具有不同的角色。我发现仅使用SQL设置角色是最简单的。我们现在开始吧。 打开SQL Server Management Studio,像这样在as (localdb)v11.0中输入服务器名,然后点击连接: 你应该会看到一个名为aspnet-Awesome Angular Web App 2.0-20141116095710的数据库,最后的数字就是这个数据库创建时的时间戳。 让我们创建一个名为SuperAdmin的角色,并分配我们创建该角色的用户。使用以下SQL语句更新AspNetRoles表: 隐藏,复制Code

    INSERT INTO [aspnet-Awesome Angular Web App 2.0-20141116095710].[dbo].[AspNetRoles] VALUES('8138aad6-dfdb-422d-862d-8d5acab5c8a1', 'SuperAdmin')

    现在让我们更新ValuesController,使其只允许超级管理员获取值。像这样修改控制器上的[Authorize]属性: 隐藏,复制Code

    [Authorize(Roles = "SuperAdmin")]

    重要提示:当我们停止和启动API时,我们的令牌将不再工作,因为它们存储在内存中,所以你将需要清除你的浏览器缓存在同一时间。 现在,当我们去我们的网站和登录(与以下凭据为懒惰): 用户名:email@email.com密码:Password1! 我们得到了401未经授权的赔偿。这是因为我们不是超级管理员组的成员。让我们解决这个问题,首先运行以下SQL对[AspNetUsers]看看我们的id是: 隐藏,复制Code

    SELECT [Id] FROM [aspnet-Awesome Angular Web App 2.0-20141116095710].[dbo].[AspNetUsers] WHERE [Email] = 'email@email.com'

    对我来说,id是e79c2336-265e-42d0-a62c-df44a3dfa0f4,你的会不一样,所以在下面的SQL中将这个id替换为你的。下面的SQL将用户添加到角色中: 隐藏,复制Code

    INSERT INTO [aspnet-Awesome Angular Web App 2.0-20141116095710].[dbo].[AspNetUserRoles] VALUES('e79c2336-265e-42d0-a62c-df44a3dfa0f4', '8138aad6-dfdb-422d-862d-8d5acab5c8a1')

    你现在是一个超级管理员,但你不是当你登录时,所以清空你的浏览器缓存,登录现在再试一次。如果一切正常,您将能够成功地完成针对Values控制器的HTTP请求,但是不属于超级管理员角色的其他用户则不能。 回顾 今天,我们用ASP创建了一个RESTful API。Net Web API,一个运行在node.js服务器上的AngularJS应用程序,并成功配置该应用程序根据API进行身份验证,将令牌存储在cookie中的a中。我们还创建了一个角色,并将API的一个区域限制为该角色的用户。 接下来是第四部分 你想看什么?留下你的评论。 安全 来自微软的Troy Hunt使用本文中的代码作为Pluralsight客户端框架安全课程的基础。我强烈建议你去看看。 评论/批评等 如果有任何评论/批评/问题,请对这篇文章发表评论,我会回复你的。感谢你的阅读 本文转载于:http://www.diyabc.com/frontweb/news1693.html

  • 相关阅读:
    CentOS7下Elastic Stack 5.0日志分析系统搭建
    ElasticSearch 简单入门
    简单使用packetbeat
    centos7没有安装ifconfig命令的解决方法
    CentOS系统下docker的安装与卸载
    centos7 cannot find a valid baseurl for repo base
    HP P2xxx/MSA SMI-S Provider
    Zookeeper 的学习与运用
    kafka入门:简介、使用场景、设计原理、主要配置及集群搭建(转)
    利用开源架构ELK构建分布式日志系统
  • 原文地址:https://www.cnblogs.com/Dincat/p/13456306.html
Copyright © 2020-2023  润新知