用户权限管理实现

基于角色的访问控制(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)
    }
  }
})

更多推荐