java如何做权限管理

发布网友 发布时间:2022-04-25 16:01

我来回答

12个回答

懂视网 时间:2022-05-15 01:35

本篇文章给大家详细讲解了如何在权限管理模块中动态的加载VUE组件的过程,有这方面需求的朋友跟着学习下吧。

本文我们主要来聊聊登录以及组件的动态加载。

登录状态保存

当用户登录成功之后,需要将当前用户的登录信息保存在本地,方便后面使用。具体实现如下:

登录成功保存数据

在登录操作执行成功之后,通过commit操作将数据提交到store中,核心代码如下:

this.postRequest('/login', {
 username: this.loginForm.username,
 password: this.loginForm.password
}).then(resp=> {
 if (resp && resp.status == 200) {
 var data = resp.data;
 _this.$store.commit('login', data.msg);
 var path = _this.$route.query.redirect;
 _this.$router.replace({path: path == '/' || path == undefined ? '/home' : path});
 }
});

store

store的核心代码如下:

export default new Vuex.Store({
 state: {
 user: {
 name: window.localStorage.getItem('user' || '[]') == null ? '未登录' : JSON.parse(window.localStorage.getItem('user' || '[]')).name,
 userface: window.localStorage.getItem('user' || '[]') == null ? '' : JSON.parse(window.localStorage.getItem('user' || '[]')).userface
 }
 },
 mutations: {
 login(state, user){
 state.user = user;
 window.localStorage.setItem('user', JSON.stringify(user));
 },
 logout(state){
 window.localStorage.removeItem('user');
 }
 }
});

为了减少麻烦,用户登录成功后的数据将被保存在localStorage中(防止用户按F5刷新之后数据丢失),以字符串的形式存入,取的时候再转为json。当用户注销登陆时,将localStorage中的数据清除。

组件动态加载

在权限管理模块中,这算是前端的核心了。

核心思路

用户在登录成功之后,进入home主页之前,向服务端发送请求,要求获取当前的菜单信息和组件信息,服务端根据当前用户所具备的角色,以及角色所对应的资源,返回一个json字符串,格式如下:

[
 {
 "id": 2,
 "path": "/home",
 "component": "Home",
 "name": "员工资料",
 "iconCls": "fa fa-user-circle-o",
 "children": [
 {
 "id": null,
 "path": "/emp/basic",
 "component": "EmpBasic",
 "name": "基本资料",
 "iconCls": null,
 "children": [],
 "meta": {
  "keepAlive": false,
  "requireAuth": true
 }
 },
 {
 "id": null,
 "path": "/emp/adv",
 "component": "EmpAdv",
 "name": "高级资料",
 "iconCls": null,
 "children": [],
 "meta": {
  "keepAlive": false,
  "requireAuth": true
 }
 }
 ],
 "meta": {
 "keepAlive": false,
 "requireAuth": true
 }
 }
]

前端在拿到这个字符串之后,做两件事:1.将json动态添加到当前路由中;2.将数据保存到store中,然后各页面根据store中的数据来渲染菜单。

核心思路并不难,下面我们来看看实现步骤。

数据请求时机

这个很重要。

可能会有小伙伴说这有何难,登录成功之后请求不就可以了吗?是的,登录成功之后,请求菜单资源是可以的,请求到之后,我们将之保存在store中,以便下一次使用,但是这样又会有另外一个问题,假如用户登录成功之后,点击某一个子页面,进入到子页面中,然后按了一下F5进行刷新,这个时候就GG了,因为F5刷新之后store中的数据就没了,而我们又只在登录成功的时候请求了一次菜单资源,要解决这个问题,有两种思路:1.将菜单资源不要保存到store中,而是保存到localStorage中,这样即使F5刷新之后数据还在;2.直接在每一个页面的mounted方法中,都去加载一次菜单资源。

由于菜单资源是非常敏感的,因此最好不要不要将其保存到本地,故舍弃方案1,但是方案2的工作量有点大,因此我采取办法将之简化,采取的办法就是使用路由中的导航守卫。

路由导航守卫

我的具体实现是这样的,首先在store中创建一个routes数组,这是一个空数组,然后开启路由全局守卫,如下:

router.beforeEach((to, from, next)=> {
 if (to.name == 'Login') {
 next();
 return;
 }
 var name = store.state.user.name;
 if (name == '未登录') {
 if (to.meta.requireAuth || to.name == null) {
 next({path: '/', query: {redirect: to.path}})
 } else {
 next();
 }
 } else {
 initMenu(router, store);
 next();
 }
 }
)

这里的代码很短,我来做一个简单的解释:

1.如果要去的页面是登录页面,这个没啥好说的,直接过。

2.如果不是登录页面的话,我先从store中获取当前的登录状态,如果未登录,则通过路由中meta属性的requireAuth属性判断要去的页面是否需要登录,如果需要登录,则跳回登录页面,同时将要去的页面的path作为参数传给登录页面,以便在登录成功之后跳转到目标页面,如果不需要登录,则直接过(事实上,本项目中只有Login页面不需要登录);如果已经登录了,则先初始化菜单,再跳转。

初始化菜单的操作如下:

export const initMenu = (router, store)=> {
 if (store.state.routes.length > 0) {
 return;
 }
 getRequest("/config/sysmenu").then(resp=> {
 if (resp && resp.status == 200) {
 var fmtRoutes = formatRoutes(resp.data);
 router.addRoutes(fmtRoutes);
 store.commit('initMenu', fmtRoutes);
 }
 })
}
export const formatRoutes = (routes)=> {
 let fmRoutes = [];
 routes.forEach(router=> {
 let {
 path,
 component,
 name,
 meta,
 iconCls,
 children
 } = router;
 if (children && children instanceof Array) {
 children = formatRoutes(children);
 }
 let fmRouter = {
 path: path,
 component(resolve){
 if (component.startsWith("Home")) {
 require(['../components/' + component + '.vue'], resolve)
 } else if (component.startsWith("Emp")) {
 require(['../components/emp/' + component + '.vue'], resolve)
 } else if (component.startsWith("Per")) {
 require(['../components/personnel/' + component + '.vue'], resolve)
 } else if (component.startsWith("Sal")) {
 require(['../components/salary/' + component + '.vue'], resolve)
 } else if (component.startsWith("Sta")) {
 require(['../components/statistics/' + component + '.vue'], resolve)
 } else if (component.startsWith("Sys")) {
 require(['../components/system/' + component + '.vue'], resolve)
 }
 },
 name: name,
 iconCls: iconCls,
 meta: meta,
 children: children
 };
 fmRoutes.push(fmRouter);
 })
 return fmRoutes;
}

在初始化菜单中,首先判断store中的数据是否存在,如果存在,说明这次跳转是正常的跳转,而不是用户按F5或者直接在地址栏输入某个地址进入的。否则就去加载菜单。拿到菜单之后,首先通过formatRoutes方法将服务器返回的json转为router需要的格式,这里主要是转component,因为服务端返回的component是一个字符串,而router中需要的却是一个组件,因此我们在formatRoutes方法中动态的加载需要的组件即可。数据格式准备成功之后,一方面将数据存到store中,另一方面利用路由中的addRoutes方法将之动态添加到路由中。

菜单渲染

最后,在Home页中,从store中获取菜单json,渲染成菜单即可,相关代码可以在Home.vue中查看,不赘述。

OK,如此之后,不同用户登录成功之后就可以看到不同的菜单了。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

在vue.js中如何获取select中的value值(详细教程)

在Vue2.0系列中如何使用过滤器?

在vue项目中通过tween方法如何实现返回顶部

使用vue如何判断input输入内容全是空格?

使用js判断输入框不能为空格或null值该如何实现?

热心网友 时间:2022-05-14 22:43

首先介绍下思路:

1、用户表 user;

2、角色表 role;

3、菜单 menu;

4、角色菜单权限表 role_menu;

5、用户菜单权限表 user_menu;

如图:

根据用户角色取出该角色所有权限,并对用户进行权限分配;注意菜单的按钮(新增、删除、修改)权限是放在中间表(user_menu)中的;

1、新增用户时,是要根据用户角色进行分配权限的 一定记得批量添加;批量、批量、批量,重要的事情说三遍,不要查询角色权限,然后for循环,这样效率太低了;

SQL如下:

INSERT INTO sys_user_menu(UserId, MenuId, DelPower,    UpdPower,    InsPower,    ViewPower)
SELECT #{userId} UserId, MenuId, 1 DelPower, 1 UpdPower, 1 InsPower, 1 ViewPower FROM sys_role_menu WHERE RoelId = #{roleId}

updPower 默认都是有的 所以都是1,这样根据角色查询出权限直接添加,响应时间大大提升;

2、修改用户角色也要记得重新分配用户权限哦!这个不能忘,可以用上面的方法;

业务方法:


如果角色没有修改,是不用重新分配权限的,所有userRole 重置为 null,如果角色修改则删除原权限,重新进行分配;

3、最后要优化的就是根据用户查询权限的时候啦,我最开始是这样做的,查询角色权限,用户权限,返回到前端,前端进行处理;结果就是很卡 基本上要三到四秒,

解决方案,一步到位;一个查询返回全部数据。

如下SQL:

SELECT menu.MenuId id, ParentId pid, MenuName text,
(SELECT COUNT(1) FROM sys_user_menu WHERE UserId = #{userId} AND  MenuId = sm.MenuId) isShow,
(SELECT CONCAT(
(CASE WHEN smenu.InsPower = 1 THEN 1 ELSE 0 END), ',',
(CASE WHEN smenu.DelPower = 1 THEN 1 ELSE 0 END), ',',
(CASE WHEN smenu.UpdPower = 1 THEN 1 ELSE 0 END), ',',
(CASE WHEN smenu.ViewPower = 1 THEN 1 ELSE 0 END))
FROM sys_user_menu smenu WHERE smenu.UserId = #{userId}
AND  smenu.MenuId = sm.MenuId) MenuInfo
FROM sys_role_menu sm INNER JOIN sys_menu menu on sm.MenuId = menu.MenuId
WHERE RoelId = #{roleId}

首先根据 角色ID查询出权限,然后子查询用户是否有该权限,有返回1 木用返回 0;

最后按钮权限 我是直接拼接成字符串,分别对应 添加、删除、修改、查看 1 有该按钮 0 没有该按钮;

优化后 不管是添加、修改用户,加载用户权限都能控制在 1~2 秒;

热心网友 时间:2022-05-15 00:01

思路:

1、用户表 user;

2、角色表 role;

3、菜单 menu;

4、角色菜单权限表 role_menu;

5、用户菜单权限表 user_menu;

Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程[1]  。

Java具有简单性、面向对象、分布式、健壮性、安全性、平*立与可移植性、多线程、动态性等特点[2]  。Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等[3]  。

由于在开发Oak语言时,尚且不存在运行字节码的硬件平台,所以为了在开发时可以对这种语言进行实验研究,他们就在已有的硬件和软件平台基础上,按照自己所指定的规范,用软件建设了一个运行平台,整个系统除了比C++更加简单之外,没有什么大的区别。1992年的夏天,当Oak语言开发成功后,研究者们向硬件生产商进行演示了Green操作系统、Oak的程序设计语言、类库和其硬件,以说服他们使用Oak语言生产硬件芯片,但是,硬件生产商并未对此产生极大的热情。因为他们认为,在所有人对Oak语言还一无所知的情况下,就生产硬件产品的风险实在太大了,所以Oak语言也就因为缺乏硬件的支持而无法进入市场,从而被搁置了下来。

1994年6、7月间,在经历了一场历时三天的讨论之后,团队决定再一次改变了努力的目标,这次他们决定将该技术应用于万维网。他们认为随着Mosaic浏览器的到来,因特网正在向同样的高度互动的远景演变,而这一远景正是他们在有线电视网中看到的。作为原型,帕特里克·诺顿写了一个小型万维网浏览器WebRunner。[4] 

1995年,互联网的蓬勃发展给了Oak机会。业界为了使死板、单调的静态网页能够“灵活”起来,急需一种软件技术来开发一种程序,这种程序可以通过网络传播并且能够跨平台运行。于是,世界各大IT企业为此纷纷投入了大量的人力、物力和财力。这个时候,Sun公司想起了那个被搁置起来很久的Oak,并且重新审视了那个用软件编写的试验平台,由于它是按照嵌入式系统硬件平台体系结构进行编写的,所以非常小,特别适用于网络上的传输系统,而Oak也是一种精简的语言,程序非常小,适合在网络上传输。Sun公司首先推出了可以嵌入网页并且可以随同网页在网络上传输的Applet(Applet是一种将小程序嵌入到网页中进行执行的技术),并将Oak更名为Java(在申请注册商标时,发现Oak已经被人使用了,再想了一系列名字之后,最终,使用了提议者在喝一杯Java咖啡时无意提到的Java词语)。5月23日,Sun公司在Sun world会议上正式发布Java和HotJava浏览器。IBM、Apple、DEC、Adobe、HP、Oracle、Netscape和微软等各大公司都纷纷停止了自己的相关开发项目,竞相购买了Java使用许可证,并为自己的产品开发了相应的Java平台。

热心网友 时间:2022-05-15 01:36

我知道有两种可以解决
1:用过滤器过滤请求,按照权限级别给出能访问的特定的界面,这种方法可能会有很多的界面,且界面重用性不高;
2:按照权限来显示界面,不同权限的人看到不同作用的界面;
建议两种方法混合在一起用

热心网友 时间:2022-05-15 03:27

权限管理???如果我没理解错的话,管理员在数据库里设置管理权限,例如:设置为授权,再执行某个功能的jframe或者class时,先读取数据库里的权限字段,若权限是:授权,则执行某一对象,若权限是:禁权,则是某一frame或功能为不可用,这样再给管理员设置一个发放权限收回权限的按钮,这样管理员可以通过修改数据库的权限字段来随时控制用户的权限,很简单的,总之就是在使用前先进行数据库权限的读取···

热心网友 时间:2022-05-15 05:35

加个权限表,关联用户表,目测是多对多的关系。有了这个,你用户登录上去之后一查就可以了。权限表里还可以细化,分部门啊、分菜单啊等等。权限组你可以把它当用户一样处理,这时候就是自关联。或者单独出来一个表,用户查询权限的时候判断有没有组来判断权限。

热心网友 时间:2022-05-15 08:00

首先需要这样几张表:资源表、角色资源表、角色表、用户角色表、用户表。资源就是你所谓的权限无论是菜单权限还是操作权限都在这里面,将资源分配给角色,再讲角色分配给用户,这样实现了用户权限管理。在资源表中应该有一个资源标识,这样在操作这个资源的时候 我们就可以通过用户所拥有的资源标识去比对,如果存在说明有权限,不存在则没有

热心网友 时间:2022-05-15 10:41

数据库设置用户标志。1.2.3等等。1管理员,2,普通用户。就这样

热心网友 时间:2022-05-15 13:39

1.在登陆页面之后,想点一个按钮提交,需要有这么权限才能看见或者才能点的话,可以做一个简单的判断,比如if(如果有这个权限,那么可以点或者可以看见),这时就做了一个简单的权限。
2.权限是在数据库中存着的。

3.角色是什么,角色关联了很多的权限,登陆之后判断有几个角色,然后在辨别角色之后就拿到了所有权限,这时候按钮那就可以判断了,当然这是比较笨的方法,原理都是这样子,也有很多权限框架会比较方便。

热心网友 时间:2022-05-15 16:54

你说的就是简单的角色权限。这些在网上有很多的教程,而且比较简单,我可以给你一点提示
1:如果你登陆页面之后,比如想点一个按钮提交,那么如果你有这么权限才能看见或者才能点的话,那么你可以做一个简单的判断,比如if(如果有这个权限,那么可以点或者可以看见),这时就做了一个简单的权限。
2:那么你的权限哪来的,数据库中存着。
3:角色是什么,角色关联了很多的权限,你登陆之后判断你几个角色,然后在遍历你的角色就拿到了你的所有权限,那么按钮那就可以判断了,当然这是比较笨的方法,原理都是这样子,也有很多权限框架会比较方便
不理解可以问我追问spring的security太难了 我看不懂啊,不用什么框架的 自已弄一个呢?
第3和第4问 该如何设计呢?
请明示

热心网友 时间:2022-05-15 20:25

数据库设计的时候 1、用户表 2、角色表(对应组) 3、菜单表
用户关联角色 ,角色关联菜单
页面的显示用动态的形式,根据登录用户 查询出可显示的菜单集合,在页面循环显示

按钮这级没啥好的经验,原来用过对每个按钮做权限判断是否显示,感觉很失败,坐等高手

热心网友 时间:2022-05-16 00:13

你说的就是简单的角色权限。这些在网上有很多的教程,而且比较简单,我可以给你一点提示 1:如果你登陆页面之后,比如想点一个按钮提交,那么如果你有这么权限才能看见或者才能点的话,那么你可以做一个简单的判断,比如if(如果有这个权限

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com