博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在AngularJS应用中实现认证授权
阅读量:4130 次
发布时间:2019-05-25

本文共 3495 字,大约阅读时间需要 11 分钟。

在AngularJS应用中实现认证授权

在每一个严肃的应用中,认证和授权都是非常重要的一个部分。单页应用也不例外。应用并不会将所有的数据和功能都 暴露给所有的用户。用户需要通过认证和授权来查看应用的某个特定部分,或者在应用中进行特定的行为。为了在应用中对用户进行识别,我们需要让用户进行登录。

在用户管理方面,传统的服务器端应用和单页应用的实现方式有所不同,单页应用能够和服务器通信的方式只有AJAX。对于登录和退出来说也是如此。

负责识别用户的服务器端需要暴露出一个认证断电。单页应用将会把用户输入的信息发送到这个节点进行认证。在一个基于认证系统的典型token中,这项服务用于在认证完毕之后获取一个token或者一个包含已登录用户的名字和角色信息的对象。客户端则需要在所有的安全API中获取这个token。

由于获取toekn的行为将会多次发生,我们最好将这个token存在客户端。在Angular中,我们可以将这个值存在一个服务中,因为服务在客户端中是一个单体。但是,如果用户刷新了页面,服务中的值将会丢失。在这种情况下,最好将值存放在一个有浏览器提供的安全存储中,在这里我们要是用的是sessionStorage,因为它在浏览器关闭时会自动被清空。

实现登录

我们现在来看一些代码。假设我们已经实现了所有的服务器端的逻辑,并且有一个叫做api/login的REST接口进行登录认证,它将返回一个token。我们来写一个简单的服务用于用户登录。在后面我们会为这个服务逐渐添加功能:

app.factory("authenticationSvc", function($http, $q, $window) {  var userInfo;  function login(userName, password) {    var deferred = $q.defer();    $http.post("/api/login", {      userName: userName,      password: password    }).then(function(result) {      userInfo = {        accessToken: result.data.access_token,        userName: result.data.userName      };      $window.sessionStorage["userInfo"] = JSON.stringify(userInfo);      deferred.resolve(userInfo);    }, function(error) {      deferred.reject(error);    });    return deferred.promise;  }  return {    login: login  };});

在实际的代码中,你可能会想要将存储的代码重构为一个单独的服务。在这里为了简单起见,我们只是将它放在他用一个服务中。这个服务可以被一个用于处理登录功能的控制器所用。

安全路由

我们需要在应用中设置一些安全路由。如果一个用户没有登录同时想要进入到某一个安全路由中,他应该被重定向到登录页。我们可以使用路由选项中的resolve来实现这个功能。下面的代码片段展示了其中一种实现思路:

$routeProvider.when("/", {  templateUrl: "templates/home.html",  controller: "HomeController",  resolve: {    auth: ["$q", "authenticationSvc", function($q, authenticationSvc) {      var userInfo = authenticationSvc.getUserInfo();      if (userInfo) {        return $q.when(userInfo);      } else {        return $q.reject({ authenticated: false });      }    }]  }});

resolve块可以包含多个代码块,这些代码块将会在完成时返回promise对象。为了说明,上面代码中的auth并不在框架中,而是我们自己定义的。你可以根据你的需求来进行修改。

通过或者拒绝路由的原因有很多种。在这里的情形中,你可以在解析/拒绝一个promise的时候传递一个对象。我们在服务中还没有实现getLoggedInUser()方法。它是一个很简单的方法,能够从服务中返回loggedInUser对象。

app.factory("authenticationSvc", function() {  var userInfo;  function getUserInfo() {    return userInfo;  }});

通过上面的代码中的promise发送的想将会通过$rootScope进行广播。如果路由被解析,那么$routeChangeSuccess事件将会被广播。然而,如果路由失败,那么事件$touteChangeError将会被广播。我们将监听$routeChangeError事件并将用户重定向到登录页上。由于事件是在$rootScope层级上,最好在run函数中绑定事件处理器。

app.run(["$rootScope", "$location", function($rootScope, $location) {  $rootScope.$on("$routeChangeSuccess", function(userInfo) {    console.log(userInfo);  });  $rootScope.$on("$routeChangeError", function(event, current, previous, eventObj) {    if (eventObj.authenticated === false) {      $location.path("/login");    }  });}]);

处理页面刷新

当用户刷新页面时,服务将会失去现有状态。我们需要从浏览器的session storage中获取数据并将这些值赋值给loggerInUser变量。由于一个factory只会被调用一次,我们需要在一个初始化函数中设置这个变量,代码如下所示:

    function init() {      if ($window.sessionStorage["userInfo"]) {        userInfo = JSON.parse($window.sessionStorage["userInfo"]);      }    }init();

退出

当用户想要从应用中退出时,相应的API必须连同包含在请求头部中的token一起被调用。一旦用户退出,我们还需要清空sessionstorage中的数据。下面例子包含了一个退出函数,这个函数需要被添加到认证服务中。

function logout() {  var deferred = $q.defer();  $http({    method: "POST",    url: logoutUrl,    headers: {      "access_token": userInfo.accessToken    }  }).then(function(result) {    $window.sessionStorage["userInfo"] = null;    userInfo = null;    deferred.resolve(result);  }, function(error) {    deferred.reject(error);  });  return deferred.promise;}

总结

单页应用的认证方式和传统web应用的认证方式非常不同。由于主要的工作都搬到了浏览器端,用户的状态也需要存储在客户端。重要的一点是要记住用户的状态也需要的服务器端保存和进行验证,因为骇客很可能慧聪客户端窃取用户的数据。

转载地址:http://mxbvi.baihongyu.com/

你可能感兴趣的文章
二,nutch 1.0 web应用部署
查看>>
nutch分布式搭建
查看>>
Linux下Nutch分布式配置和使用
查看>>
Hadoop快速入门
查看>>
在SuSE集群上安装配置HDFS
查看>>
开发基于 Nutch 的集群式搜索引擎
查看>>
Lucene 2.4里一些过期方法的解决方案
查看>>
架设NFS服务器
查看>>
Eclipse在linux下的安装问题
查看>>
文本文件读取和写入
查看>>
Java 文本文件和二进制文件的读取(转)
查看>>
两个字符串相等的布尔值
查看>>
hibernate Restrictions用法
查看>>
struts2 json插件
查看>>
javascript longtoip
查看>>
Spring定时器的两种实现方式
查看>>
linux 统计当前目录下文件数
查看>>
更改SVN登录用户
查看>>
JSTL
查看>>
在Linux系统下手动安装上传rz和下载sz命令软件包
查看>>