vue-element-admin整合spring-boot权限设计之实现用户授权功能

vue-element-admin整合spring-boot权限设计之实现用户授权功能

前言

这篇文章笔者紧接着上一篇权限设计的文章vue-element-admin整合spring-boot实现权限控制之用户管理篇

我们来实现给用户添加与删除角色的功能。本文的功能实现依赖于笔者上传到gitee上的两个前后端项目,分别是江南一点雨开源的blog-server项目和花裤衩开源的vue-element-admin项目,文末会附上笔者提交到gitee上的源项目地址。

1 实现后端接口开发

1.1 查询用户未授权角色接口

1) Dao层代码开发

RolesMapper.java

List<Role> getUserNotAllocateRoles(Long uid);

RolesMapper.xml

<select id="getUserNotAllocateRoles" parameterType="java.lang.Long" resultType="org.sang.pojo.Role">
SELECT r.id,
r.role_code as roleCode,
r.role_name as roleName
FROM roles r
where r.id not in
(select rid
from roles_user
where uid = #{uid,jdbcType=BIGINT}
)
</select>

2) Service层代码

RoleService.java

public List<Role> getUserNotAllocateRoles(Long uid){
List<Role> notAllocateRoles = rolesMapper.getUserNotAllocateRoles(uid);
return notAllocateRoles;
}

3)Controller层代码

@GetMapping("/userNotAllocateRoles")
public RespBean getUserNotAllocateRoles(@RequestParam("uid") Long uid){
logger.info("uid={}",uid);
List<Role> roles = roleService.getUserNotAllocateRoles(uid);
RespBean respBean = new RespBean(200, "success");
respBean.setData(roles);
return respBean;
}

1.2 给用户添加角色接口

1) Dao层代码

RolesMapper.java

int setUserRoles(@Param("roleIds") List<Integer> roleIds, @Param("uid") Long uid);

RolesMapper.xml

<insert id="setUserRoles" keyProperty="id" useGeneratedKeys="true">
INSERT INTO roles_user(rid,uid) VALUES
<foreach collection="roleIds" item="roleId" separator=",">
(#{roleId,jdbcType=INTEGER},#{uid,jdbcType=INTEGER})
</foreach>
</insert>

2)  Service层代码

public int addRolesForUser(List<Integer> roleIds, Long uid) {
int count = rolesMapper.setUserRoles(roleIds, uid);
return count;
}

3) Controller层代

 @PostMapping(path = "/addRolesForUser")
public RespBean addRolesForUser(@RequestBody List<Integer> roleIds, @RequestParam("uid") Long uid) {
logger.info("uid={}",uid);
int addCount = roleService.addRolesForUser(roleIds, uid);
RespBean respBean = new RespBean(200, "success");
respBean.setData(addCount);
return respBean;
}

1.3 解除用户绑定角色接口

1) Dao层代码

RolesMapper.java

int delUserRoles(@Param("roleIds") List<Integer> roleIds, @Param("uid") Long uid);

RolesMapper.xml

    <delete id="delUserRoles">
DELETE FROM roles_user where rid
in <foreach collection="roleIds" item="roleId" open="(" close=")" separator=",">
#{roleId, jdbcType=INTEGER}
</foreach>
and uid = #{uid, jdbcType=BIGINT}
</delete>

2) Service层代码

RoleService.java

public int delUserRoles(List<Integer> roleIds, Long uid){
int delCount = rolesMapper.delUserRoles(roleIds, uid);
return delCount;
}

3) Controller层代码

@DeleteMapping("/userRoles")
public RespBean delUserRoles(@RequestBody List<Integer> roleIds, @RequestParam("uid") Long uid){
logger.info("uid={}",uid);
int delCount = roleService.delUserRoles(roleIds, uid);
RespBean respBean = new RespBean(200, "success");
respBean.setData(delCount);
return respBean;
}

以上每个接口完成开发后可启动后台服务器,通过postaman先调用登录接口,然后依次测试每个新开发的接口,之前的文章里有过很多如何使用postman这款API可视化工具测试接口,这里不再赘述。不懂的读者也可以通过CSDN博客搜索postman的具体用法。

2 实现前端视图组件与方法逻辑

2.1 前端添加新增接口方法

src/api/role.js文件中添加后台对应的三个接口的请求方法


/**
* 查找用户未分配角色
* @param {用户ID} uid
* @returns Promise
*/

export function getUserNotAllocateRoles(uid) {
return request({
url: `/role/userNotAllocateRoles?uid=${uid}`,
method: 'get'
})
}

/**
* 给用户添加角色
* @param {要授权的角色ID集合} roleIds
* @param {用户ID} uid
* @returns Promise
*/

export function addRolesForUser(roleIds, uid) {
return request({
url: `/role/addRolesForUser?uid=${uid}`,
method: 'post',
data: roleIds
})
}

/**
* 删除用户角色
* @param {要解除授权的角色ID集合} roleIds
* @param {用户ID} uid
* @returns Promise
*/

export function delRolesForUser(roleIds, uid) {
return request({
url: `/role/userRoles?uid=${uid}`,
method: 'delete',
data: roleIds
})
}

2.2 用户管理组件添加分配角色对话框并绑定按钮方法

views/permission/UserManage.vue文件中的查看用户角色对话框下面添加类名为edit-dialog的分配角色对话框, 查询用户角色对话框也作了部分修改,对话框标题该为指定选中用户,同时在查询用户角色的对话框中可对用户进行解除绑定授权角色的操作。

<el-dialog class="query-dialog" :title="queryDialogTitle" :visible.sync="queryDialogVisible" 
width="35%">
<el-table ref="qeuryDialogTable" :data="userRoles" highlight-current-row
@current-change="handleCurrentRowChange" style="width: 100%" @select="checkRoles"
>

<el-table-column type="selection" width="55">
</el-table-column>
<el-table-column property="id" label="角色ID" width="80">
</el-table-column>
<el-table-column property="roleCode" label="角色编码" width="120">
</el-table-column>
<el-table-column property="roleName" label="角色名称" width="120">
</el-table-column>
</el-table>

<span slot="footer" class="dialog-footer">
<el-button @click="closeQueryDialog">取 消</el-button>
<el-button type="primary" @click="delUserRole">解除授权</el-button>
</span>

</el-dialog >
<el-dialog class="edit-dialog" :title="editDialogTitle" :visible.sync="eidtDialogVisible" width="35%">
<el-table ref="editDialogTable" :data="noAllocateRoles" highlight-current-row
style="width: 100%" tooltip-effect="dark"
@selection-change="handleSelectionChange" @select="selectChecked">
<el-table-column type="selection" width="55">
</
el-table-column>
<el-table-column property="id" label="角色ID" width="80">
</el-table-column>

<el-table-column property="roleCode" label="角色编码" width="120">
</el-table-column>

<el-table-column property="roleName" label="角色名称" width="120">
</el-table-column>

</el-table>
<span slot="footer" class="dialog-footer">
<el-button @click="closeEidtDialog">取消</
el-button>
<el-button type="primary" @click="addUserRole">添加授权</el-button>
</span>
</
el-dialog>

<script>
import {getRolesByUid, getUserNotAllocateRoles, addRolesForUser, delRolesForUser} from '@/api/role'
// 省略了上一篇文章中贴过的一部分js代码
export default {
data() {
return {
queryDialogVisible: false,
eidtDialogVisible: false,
currentRoleRow: 0,
selectedUid: null,
queryDialogTitle: '',
editDialogTitle: '',
checkedRoles: [],
multipleSelection: [],
noAllocateRoles: [],
}
},
methods: {
openEditDialog(row){
console.log(row)
this.eidtDialogVisible = true
const uid = row.id
this.selectedUid = uid
this.editDialogTitle = '给用户 '+row.nickname+' 添加角色'
getUserNotAllocateRoles(uid).then(res=>{
if(res.status===200 && res.data.status===200){
this.noAllocateRoles = res.data.data
}
}).catch(err=>{
console.error(err)
})
},
handleSelectionChange(rows){

},
checkRoles(selection,row){
this.checkedRoles = selection
},
selectChecked(selection,row){
this.multipleSelection = selection
},
closeQueryDialog(){
this.queryDialogVisible = false
},
handleCurrentRowChange(row){
this.currentRoleRow = row
this.$refs['qeuryDialogTable'].setCurrentRow(row)
},
closeEidtDialog(){
this.eidtDialogVisible = false
},
addUserRole(){
if (this.multipleSelection.length > 0) {
let roleIds = []
const uid = this.selectedUid
for (let i = 0; i < this.multipleSelection.length; i++) {
let row = this.multipleSelection[i];
roleIds.push(row.id)
}
addRolesForUser(roleIds, uid).then(res=>{
if (res.status===200 && res.data.status===200) {
this.$message({
showClose: true,
message: '授权角色成功',
type: 'success'
})
}
}).catch(err=>{
this.$message({
showClose: true,
message: '授权角色成功失败',
type: 'error'
})
})
}else{
this.$message({
showClose: true,
message: '请先选择授权的角色',
type: 'warning'
})
}
this.eidtDialogVisible = false
},
delUserRole() {
if(this.checkedRoles.length > 0){
let roleIds = []
const uid = this.selectedUid
for (let i = 0; i < this.checkedRoles.length; i++) {
let row = this.checkedRoles[i];
roleIds.push(row.id)
}
delRolesForUser(roleIds, uid).then(res=>{
if(res.status===200 && res.data.status===200){
this.$message({
showClose: true,
message: '解除授权角色成功',
type: 'success'
})
}
}).catch(err=>{
this.$message({
showClose: true,
message: '解除授权角色失败',
type: 'error'
})
})
}else{
this.$message({
showClose: true,
message: '请先选择要解除授权的角色',
type: 'warning'
})
}
this.queryDialogVisible = false
}
}
}
</script>

使用el-table组件中的select事件绑定方法拿到复选框中选中的角色数组,同时在data中使用一个selectedUid变量绑定当前用户ID,通过每一行用户的操作按钮进行绑定。

2.3 效果体验

通过在vue-element-admin前端项目的根目录下的控制台中执行npm run dev 运行本地开发环境服务器

App running at:
- Local: http://localhost:3000/
- Network: http://192.168.1.235:3000/

Note that the development build is not optimized.
To create a production build, run npm run build.

在浏览器中输入http://localhost:3000/ 输入用户名(heshengfu)和登录密码(heshengfu123)登录成功后进入系统首页,然后依次点击左侧的菜单栏的权限管理->用户管理进入用户管理界面

vue-element-admin整合spring-boot权限设计之实现用户授权功能

在右边的查询表单中点击事件范围输入框,在弹出的日期时间框左侧的快捷选项中选择最近三个月,点击确定按钮后,点击查询按钮出现如下用户数据界面

在第一行数据用户程序员阿福对应的操作行点击查看已有角色链接按钮,可看到页面打开了如下对话框:

vue-element-admin整合spring-boot权限设计之实现用户授权功能

选择对话框中的user角色对应的复选框,然后点击右边的解除授权,删除用户与user角色的绑定关系后,在关闭对话框后页面会弹出一个提示删除成功的消息

vue-element-admin整合spring-boot权限设计之实现用户授权功能

再次点击用户程序员阿福右边操作栏中的的增加授权角色按钮,页面打开给用户添加角色对话框

vue-element-admin整合spring-boot权限设计之实现用户授权功能

选中角色前面的复选框,然后点击右边的添加授权按钮,页面同样会弹出授权角色成功的消息提示框

vue-element-admin整合spring-boot权限设计之实现用户授权功能

好了,本文实现给用户添加授权和解除授权角色的功能就讲到这里了。

3 解决用户退出登录失败的bug

最近发现一个很严重的Bug, 那就是点击系统右上角下来框的退出按钮后,用户的缓存没有被删除,而后台调用接口的时候却提示用户未登录却没有跳转到用户登录页面去。后来启动浏览器开发者模式debugg定位才发现退出登录接口报了跨域失败的bug,导致后面清除浏览器缓存的逻辑没有走。需要修改的地方如下

3.1 后端修改代码

WebSecurityConfig类中修改configure(HttpSecurity http)方法

vue-element-admin整合spring-boot权限设计之实现用户授权功能

3.2 前端修改代码

修改src/store/modules/user.js文件中的 actions中的 logout行为

 // user logout
logout({ commit, state, dispatch }) {
return new Promise((resolve, reject) => {
if (!window.sessionStorage.getItem('userInfo')) {
Message.info('用户当前未登录登录')
resolve()
} else {
commit('SET_TOKEN', '')
commit('SET_ROLES', [])
commit('SET_NAME', '')
commit('SET_CURRENT_ROLE', null)
window.sessionStorage.removeItem('userInfo')
window.sessionStorage.removeItem('routeIds')
window.sessionStorage.removeItem('roles')
window.sessionStorage.removeItem('currentRole')
removeToken()
resetRouter()
// reset visited views and cached views
// to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2485
dispatch('tagsView/delAllViews', null, { root: true })
Message.info('退出登录成功')
resolve()
}
})
},
// remove token
resetToken({ commit }) {
return new Promise(resolve => {
commit('SET_TOKEN', '')
commit('SET_ROLES', [])
removeToken()
resolve()
})
}

这里作为一种临时的解决方案,没有向后台发送退出登录的请求了。因为笔者发现前端调用退出接口时一直报诡异的跨域失败问题,短时间之内笔者难以解决,先用这种临时方案替换了,等解决了退出接口跨域失败的问题了再来完善修改本文。

4 小结

本文主要完成了给选中用户添加角色和删除角色等功能,同时解决了一个系统退出登录失败和后端接口返回信息提示用户没有登录的情况下没有跳转到登录页面两个Bug。下一篇关于实现自定义授权功能的文章笔者将继续带领大家一起实现角色的增删改查及给角色添加资源权限等功能,敬请期待!

写文不易,诚邀看到这里的朋友都在下方点个再看,谢谢!

本文前端项目gitee地址:

https://gitee.com/heshengfu1211/vue-element-admin.git

后端项目地址:

https://gitee.com/heshengfu1211/blogserver.git


vue-element-admin整合spring-boot权限设计之实现用户授权功能

【1】实现基于用户角色的页面路由资源权限控制(后端篇)

【2】vue-element-admin整合SpringBoot实现动态渲染基于角色的菜单资源踩坑录(前后端整合篇)

【3】vue-element-admin整合spring-boot实现权限控制之用户管理篇

【4】详解面试官经常问的SpringBoot启动流程机制


原文始发于微信公众号(阿福谈Web编程):vue-element-admin整合spring-boot权限设计之实现用户授权功能

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/42315.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!