Java+MySQL开发社区论坛 用户权限管理与帖子分类实现
·
用户权限管理实现
基于角色的访问控制(RBAC)是社区论坛权限管理的核心方案。创建五张表实现完整权限体系:用户表users、角色表roles、权限表permissions、用户角色关联表user_roles和角色权限关联表role_permissions。
// Spring Security核心配置示例
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/moderator/**").hasAnyRole("MODERATOR","ADMIN")
.antMatchers("/post/create").authenticated()
.anyRequest().permitAll()
.and()
.formLogin().permitAll();
}
}
权限数据表设计采用自关联结构:
CREATE TABLE `permissions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL COMMENT '权限标识符',
`description` varchar(100) DEFAULT NULL,
`parent_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
帖子分类系统构建
树形分类结构通过闭包表实现高效查询,核心表包括分类表categories和关系表category_closure:
CREATE TABLE `categories` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`slug` varchar(50) NOT NULL,
`sort_order` int(11) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `category_closure` (
`ancestor` int(11) NOT NULL,
`descendant` int(11) NOT NULL,
`depth` int(11) NOT NULL,
PRIMARY KEY (`ancestor`,`descendant`),
KEY `idx_descendant` (`descendant`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Java层实现分类树构建:
public List<CategoryTreeVO> buildCategoryTree(List<Category> allCategories) {
Map<Integer, CategoryTreeVO> nodeMap = allCategories.stream()
.collect(Collectors.toMap(Category::getId,
c -> new CategoryTreeVO(c.getId(), c.getName())));
List<CategoryTreeVO> roots = new ArrayList<>();
nodeMap.values().forEach(node -> {
if (node.getParentId() == 0) {
roots.add(node);
} else {
nodeMap.get(node.getParentId()).addChild(node);
}
});
return roots;
}
权限-分类联合控制
在帖子服务层实现双重权限校验:
@PreAuthorize("hasPermission(#categoryId, 'category', 'write')")
public void createPost(Post post, int categoryId) {
Category category = categoryService.getById(categoryId);
if (category == null || category.getStatus() != Status.NORMAL) {
throw new BusinessException("分类不可用");
}
post.setCategoryId(categoryId);
postMapper.insert(post);
}
缓存优化策略
采用多级缓存提升权限校验性能:
@Cacheable(value = "user_permissions", key = "#userId")
public Set<String> getUserPermissions(int userId) {
return permissionMapper.selectByUserId(userId)
.stream()
.map(Permission::getName)
.collect(Collectors.toSet());
}
@CacheEvict(value = "category_tree", allEntries = true)
public void updateCategory(Category category) {
categoryMapper.updateById(category);
}
前端权限渲染控制
Vue.js实现动态路由和按钮级权限:
// 路由守卫权限检查
router.beforeEach((to, from, next) => {
const requiredPermissions = to.meta.permissions
if (requiredPermissions && !store.getters.hasPermissions(requiredPermissions)) {
next('/403')
} else {
next()
}
})
// 指令式按钮权限
Vue.directive('permission', {
inserted(el, binding, vnode) {
if (!store.getters.hasPermission(binding.value)) {
el.parentNode.removeChild(el)
}
}
})
更多推荐



所有评论(0)