分享一个自己一直在用的后台管理系统的权限管理

下面先贴出相应的数据库表

管理员信息表:
admin表
菜单表(对应vue的路由):
在这里插入图片描述
角色表:
在这里插入图片描述
角色菜单关联表:
在这里插入图片描述
思路如下:
在admin登录时,将登录时生成的token保存到vue组件。然后查询对应的角色信息,根据角色id查询role_permission表所关联的菜单权限信息,返回给vue里面控制管理系统左侧菜单栏导航的显示
在这里插入图片描述
到这里已经实现了菜单的权限控制。

下面是菜单所对应的前端页面内的增删改查的控制:

在每次前端通过http请求后端的时候,在header里面带上存储的token,
在这里插入图片描述

然后后端使用自定义注解和AOP的方式实现增删改查权限的控制。
下面是后端代码:

定义权限注解

/**
 * 自定义权限注解
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface Auth {
	String role();
	String url();
}

AOP

@Order(1)
@Component
@Aspect
@Slf4j
public class AuthAspect {
	
	@Autowired
	AuthService authService;

	@Around("@annotation(com.mikao.config.Auth)")
	public Object around(ProceedingJoinPoint pjp) throws Throwable {
		// 获取请求信息
		ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = sra.getRequest();
		// 获取代理地址、请求地址
		String remoteAddress = IpUtils.getIpAddr(request);
		// 获取token
		String token = request.getHeader("token");
		log.info("token:" + token);
		if (!StringUtils.hasText(token)) {
			log.warn("无效请求:无token IP信息->: 【{}】 ", remoteAddress);
			return BaseResult.getForbidden();
		}
		Long userId = JwtUtil.validateToken(token);
		if (ObjectUtils.isEmpty(userId) || userId == 0L) {
			log.warn("无效请求:无效的token IP信息->: 【{}】 ", remoteAddress);
			return BaseResult.getForbidden();
		}
		Boolean validateToken = authService.validateToken(userId, token);
		if (!validateToken) {
			log.warn("无效请求:token过期   IP信息->: 【{}】 ", remoteAddress);
			return BaseResult.getForbidden();
		}
		// 后台管理权限
		Auth auth = ((MethodSignature) pjp.getSignature()).getMethod().getAnnotation(Auth.class);
		if (ObjectUtils.isNull(auth) || !authService.hasAuth(userId, auth.role(), auth.url())) {
			log.warn("无效请求:无【{}】操作权限   IP信息->: 【{}】 ", auth.role(),remoteAddress);
			return BaseResult.getForbidden();
		}
		return pjp.proceed();
	}

}

AuthService.hasAuth()的实现:

@Override
public Boolean hasAuth(Long adminId, String role, String url) {
	Admin admin = adminDao.selectById(adminId);
	Permission per = permissionDao.selectOne(new QueryWrapper<Permission>().eq("url", url));
	if (ObjectUtils.isNotNull(per)) {
		RolePermission rp = rolePermissionDao
				.selectOne(new QueryWrapper<RolePermission>().eq("rid", admin.getRoleId()).eq("pid", per.getId()));
		if (ObjectUtils.isNotNull(rp)&&((role.equals("select") && rp.getpSelect() == 1) 
					|| (role.equals("insert") && rp.getpInsert() == 1)
					|| (role.equals("update") && rp.getpUpdate() == 1)
					|| (role.equals("delete") && rp.getpDelete() == 1))) {
					return true;
		}
	}
	return false;
}

最后在controller层你需要控制权限的接口上面加上该注解

@Auth(role=“select”,url=“guideImg”)
其中role的值可以是select、insert、update、delete
url的值为上面的permission菜单表里的对应需要控制权限的路由页面的url
在这里插入图片描述
在这里插入图片描述

效果如下:
在这里插入图片描述

Logo

前往低代码交流专区

更多推荐