®
世界顶尖人才,点播 ®

Toptal, LLC版权所有

\n\n\n\n\n\n\n\n\n \n\n\n

We are using ngStorage library for AngularJS, 将令牌保存到浏览器的本地存储中, 这样我们就可以通过 Authorization header.

\n\n

在生产环境中, of course, 为了提高性能,我们将最小化并组合所有脚本文件和样式表.

\n\n

我使用Bootstrap创建了一个导航栏,它将改变适当链接的可见性, 取决于用户的登录状态. 的存在来确定登录状态 token 变量在控制器的作用域中.

\n\n
\n \n JWT Angular example\n
\n\n
\n\n

Routing

\n\n

We have a file named app.js 谁负责配置我们所有的前端路由.

\n\n
angular.module('app', [\n   'ngStorage',\n   'ngRoute',\n   'angular-loading-bar'\n])\n   .constant('urls', {\n       BASE: 'http://jwt.dev:8000',\n       BASE_API: 'http://api.jwt.dev:8000/v1'\n   })\n   .配置('$routeProvider', '$httpProvider', function ($routeProvider, $httpProvider) {\n       $routeProvider.\n           when('/', {\n               templateUrl:“泛音/ home.html',\n               控制器:“HomeController”\n           }).\n           when('/signin', {\n               templateUrl:“泛音/ signin.html',\n               控制器:“HomeController”\n           }).\n           when('/signup', {\n               templateUrl:“泛音/注册.html',\n               控制器:“HomeController”\n           }).\n           when('/restricted', {\n               templateUrl:“泛音/限制.html',\n               控制器:“RestrictedController”\n           }).\n           otherwise({\n               redirectTo: '/'\n           });\n
\n\n

在这里,我们可以看到,我们已经定义了4条路由,这4条路由由任意一条处理 HomeController or RestrictedController. 每条路由都对应一个局部的HTML视图. 我们还定义了两个常量,它们包含对后端HTTP请求的url.

\n\n

Request Interceptor

\n\n

AngularJS的$http服务允许我们与后端通信并发出http请求. 在我们的示例中,我们希望拦截每个HTTP请求并向其注入 Authorization 如果用户经过身份验证,则包含JWT的头. 我们还可以使用拦截器来创建一个全局HTTP错误处理程序. 下面是我们的拦截器的一个例子,如果它在浏览器的本地存储中可用,它会注入一个令牌.

\n\n
$httpProvider.interceptors.push('$q', '$location', '$localStorage', function ($q, $location, $localStorage) {\n   return {\n       'request': function (config) {\n           config.headers = config.headers || {};\n           if ($localStorage.token) {\n               config.headers.授权= '承载者' + $localStorage.token;\n           }\n           return config;\n       },\n       'responseError':函数(response) {\n           if (response.状态=== 401 ||响应.status === 403) {\n               $location.path('/signin');\n           }\n           return $q.reject(response);\n       }\n   };\n}]);\n
\n\n

Controllers

\n\n

In the controllers.js 文件中,我们已经为应用程序定义了两个控制器: HomeController and RestrictedController. HomeController 处理登录,注册和注销功能. 它将用户名和密码数据从登录和注册表单传递给 Auth 服务,它将HTTP请求发送到后端. 然后将令牌保存到本地存储中, 或显示错误消息, 取决于后端响应.

\n\n
angular.module('app')\n   .` ` $rootScope `, ` $scope `, ` $location `, ` $localStorage `, ` Auth `,\n       函数($rootScope, $scope, $location, $localStorage, Auth) {\n           successAuth(res) {\n               $localStorage.token = res.token;\n               window.location = \"/\";\n           }\n\n           $scope.signin = function () {\n               var formData = {\n                   email: $scope.email,\n                   password: $scope.password\n               };\n\n               Auth.signin(formData, successAuth, function () {\n                   $rootScope.error = '无效凭据.';\n               })\n           };\n\n           $scope.signup = function () {\n               var formData = {\n                   email: $scope.email,\n                   password: $scope.password\n               };\n\n               Auth.注册(formData, successAuth, function () {\n                   $rootScope.error = '注册失败';\n               })\n           };\n\n           $scope.logout = function () {\n               Auth.logout(function () {\n                   window.location = \"/\"\n               });\n           };\n           $scope.token = $localStorage.token;\n           $scope.tokenClaims = Auth.getTokenClaims();\n       }])\n
\n\n

RestrictedController 行为方式相同,只是它通过使用 getRestrictedData and getApiData functions on the Data service.

\n\n
   .控制器(“RestrictedController”, ['$rootScope', '$scope', 'Data', function ($rootScope, $scope, Data) {\n       Data.gettrestricteddata(函数(res) {\n           $scope.data = res.data;\n       }, function () {\n           $rootScope.error =“获取受限内容失败”.';\n       });\n       Data.getApiData(function (res)) {\n           $scope.api = res.data;\n       }, function () {\n           $rootScope.error =“获取受限API内容失败”.';\n       });\n   }]);\n
\n\n

只有当用户经过身份验证时,后端才负责提供受限制的数据. 这意味着,为了响应受限制的数据, 对该数据的请求需要在其属性中包含有效的JWT Authorization header or query string. 如果不是这种情况,服务器将响应401未授权错误状态码.

\n\n

Auth Service

\n\n

Auth服务负责将登录和注册HTTP请求发送到后端. 如果请求成功, 响应包含已签名的令牌, 哪个是base64解码的, 所包含的令牌声明信息保存到 tokenClaims variable. 将其传递给控制器 getTokenClaims function.

\n\n
angular.module('app')\n   .factory('Auth', ['$http', '$localStorage', 'urls', function ($http, $localStorage, urls) {\n       函数urlBase64Decode(str) {\n           var output = str.replace('-', '+').replace('_', '/');\n           switch (output.length % 4) {\n               case 0:\n                   break;\n               case 2:\n                   output += '==';\n                   break;\n               case 3:\n                   output += '=';\n                   break;\n               default:\n                   非法的base64url字符串!';\n           }\n           return window.atob(output);\n       }\n\n       getClaimsFromToken() {\n           var token = $localStorage.token;\n           var user = {};\n           if (typeof token !== 'undefined') {\n               var encoded = token.split('.')[1];\n               user = JSON.解析(urlBase64Decode(编码));\n           }\n           return user;\n       }\n\n       var tokenClaims = getClaimsFromToken();\n\n       return {\n           注册:函数(数据,成功,错误){\n               $http.post(urls.BASE + '/signup', data).success(success).error(error)\n           },\n           登录:函数(数据,成功,错误){\n               $http.post(urls.BASE + '/signin', data).success(success).error(error)\n           },\n           注销:function (success) {\n               tokenClaims = {};\n               delete $localStorage.token;\n               success();\n           },\n           getTokenClaims:函数(){\n               return tokenClaims;\n           }\n       };\n   }\n   ]);\n
\n\n

Data Service

\n\n

这是一个简单的服务,它向身份验证服务器和API服务器发出请求,以获取一些虚拟的受限数据. 它发出请求,并将成功和错误回调委托给控制器.

\n\n
angular.module('app')\n   .factory('Data', ['$http', 'urls', function ($http, urls) {\n\n       return {\n           gettrestricteddata:函数(成功,错误){\n               $http.get(urls.BASE + '/restricted').success(success).error(error)\n           },\n           getApiData:函数(成功,错误){\n               $http.get(urls.BASE_API + '/restricted').success(success).error(error)\n           }\n       };\n   }\n   ]);\n
\n\n

超越这个JSON Web令牌教程

\n\n

基于令牌的身份验证使我们能够构建不绑定于特定身份验证方案的解耦系统. 令牌可以在任何地方生成,并在使用相同密钥对令牌签名的任何系统上使用. 它们是可移动的,不需要我们使用cookie.

\n\n

JSON Web令牌适用于所有流行的编程语言,并且正在迅速普及. 它们得到了谷歌(Google)、微软(Microsoft)和Zendesk等公司的支持. Internet工程任务组(IETF)的标准规范是 还在草案中 未来可能会有轻微的变化.

\n\n

关于jwt还有很多内容要介绍,例如如何处理 security details, 并在令牌到期时刷新它们, 但JSON Web令牌教程应该演示基本用法和, more importantly, 使用jwt的优点.

\n","as":"div","isContentFit":true,"sharingWidget":{"url":"http://xejg.vig2.net/web/cookie-free-authentication-with-json-web-tokens-an-example-in-laravel-and-angularjs","title":"使用AngularJS的JSON Web令牌教程 & Laravel","text":null,"providers":["linkedin","twitter","facebook"],"gaCategory":null,"domain":{"name":"developers","title":"Engineering","vertical":{"name":"developers","title":"Developers","publicUrl":"http://xejg.vig2.net/developers"},"publicUrl":"http://xejg.vig2.net/developers/blog"},"hashtags":"Authentication,JWT,Authorization,NoCookies"}}