首页 > 语言 > JavaScript > 正文

AngularJs基于角色的前端访问控制的实现

2024-05-06 15:07:21
字体:
来源:转载
供稿:网友

最近做的项目是使用Angular做一个单页应用,但因为用户有不同的角色(管理员、编辑、普通财务人员等),所以需要进行不同角色的访问控制。

因为后端访问控制的经验比较丰富,所以这里只记录了前端访问控制的实现。请注意,前端最多只能做到显示控制!并不能保证安全,所以后端是一定要做访问控制的!

基于角色的访问控制需要做到两个层面的访问控制:

    控制页面路由的跳转,没有权限的用户不能跳转到指定url 页面元素的显示控制,没有对应权限的用户不能看到该元素

但在此之前,我们还有一项重要的事要做。

存储用户信息

首先我们要做的,并不是和访问控制有关的事,首先我们要保存好用户信息。包括用户的基本信息,如用户名、真实姓名;以及用户角色。下面是数据结构:

user = {
  username:"",
  realname:"",
  role:""
}

存储的时候就将整个user存储,但存在哪里呢?考虑到必须在任何页面都可以访问到,第一反应是存储到rootScope中,但我们应该尽量避免使用rootScope;除此之外,我们可以存储在顶级的controller或者是全局的constant中,这两种解决方案都可以,但它们的问题就是一旦页面刷新,就不管用了($rootScope也一样)。考虑到user这个变量的生命周期应该要与session相同,所以,我使用了SessionStorage。

在创建controller时,需要加入$sessionStorage:

app.controller('controller',['$sessionStorage', function($sessionStorage){}]); 

在登录成功后,将user存储到SessionStorage中:

$sessionStorage.USER = user;

好了,之后通过$sessionStorage就可以获取到用户信息了。

user = $sessionStorage.USER;

控制页面路由的跳转

下面我们开始实现第一点:控制页面路由的跳转。

要做到第一点比较容易,Angular路由改变时会触发$stateChangeStart事件(我用的是stateProvider,所以监听stateChangeStart,如果是用的route或是location,应该监听它们对应的事件),监听此事件,在里面根据访问的url以及用户角色进行权限判断,比如登录的判断就可以在里面做,访问那个url需要登录就直接跳转到登录界面。

首先先写一个auth服务,用于权限认证:

/** * 基于角色的访问控制 */App.service("auth", ["$http","$sessionStorage", function($http, $sessionStorage){  var roles = []; // 从后端数据库获取的角色表  // 从后端获取的角色权限Url映射表,结构为{"role":["/page1", "/page2"……]}  var urlPermissions = {};  // 去后端获取  (function(){   // 此处为测试方便,直接赋值了,下面也仅以示例为目的,尽量简单了   roles = ["admin", "user"]   urlPermissions = {    // 管理员可以访问所用页面    "admin":["*"],     // 普通用户可以访问page路径下的所有界面(登录、注册等页面)以及系统主页    "user":["page.*", "app.index", "app.detail"]    }  })();  function convertState(state) {   return state.replace(".", "///.").replace("*", ".*");  }  return {   // 是否有访问某url的权限   isAccessUrl:function(url) {    var user = $sessionStorage.USER;    for(var role in roles) {     if(user.role.toLowerCase() == roles[role].toLowerCase()) {      console.log(urlPermissions[roles[role]])      for(i in urlPermissions[roles[role]]) {       var regx = eval("/"+convertState(urlPermissions[roles[role]][i])+"/");       console.log(regx+ " "+ url)       if(regx.test(url)) {        return true;       }      }     }    }    return false;   }  }}])            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选