首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

OA 系統權限管理實戰:登錄加載、Session 存儲、前端動態渲染

     編輯:Java 綜合教學

OA 系統權限管理實戰:登錄加載、Session 存儲、前端動態渲染

權限控制是企業級 OA 系統的核心基礎設施。本文展示一套經典的**「登錄時加載權限 → Session 存儲 → 頁面標籤判斷 → 動態渲染功能模塊」**的輕量級權限實現方案,無需重型框架(Shiro/Spring Security),適合中小型項目快速落地。

一、整體架構流程

  1. 用戶登錄認證通過
  2. 查詢用戶角色關聯的所有權限編碼/菜單 ID
  3. 將權限集合存入 Session:session.setAttribute("permissions", permissionSet)
  4. 前端頁面/JSP 標籤判斷權限:<c:if test="${permissions.contains('sys:user:add')}">
  5. 擁有權限 → 顯示對應按鈕/菜單/頁面;無權限 → 隱藏或跳轉 403

二、後端核心代碼實現

1. 登錄 Service 查詢權限

public Set<String> loadUserPermissions(Long userId) {
    // 1. 獲取用戶角色
    List<Role> roles = roleMapper.selectByUserId(userId);
    if (roles.isEmpty()) return Collections.emptySet();

    // 2. 獲取角色關聯權限 (去重)
    Set<String> permissions = new HashSet<>();
    for (Role role : roles) {
        List<Permission> perms = permissionMapper.selectByRoleId(role.getId());
        perms.forEach(p -> permissions.add(p.getCode())); // 如 "sys:user:add"
    }
    return permissions;
}

2. 登錄 Controller 存入 Session

@PostMapping("/login")
public Result login(@RequestBody LoginDTO dto, HttpSession session) {
    User user = userService.authenticate(dto.getUsername(), dto.getPassword());
    if (user == null) return Result.fail("用戶名或密碼錯誤");

    // 核心:加載權限並存 Session
    Set<String> permissions = permissionService.loadUserPermissions(user.getId());
    session.setAttribute("user", user);
    session.setAttribute("permissions", permissions); // 權限標識集合
    session.setAttribute("menus", menuService.buildUserMenus(user.getId())); // 可選:菜單樹

    return Result.ok("登錄成功");
}

三、前端動態渲染三種模式

模式 1:JSP + JSTL 標籤判斷(傳統項目)

<%@ taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core" %>
<c:if test="${permissions.contains('sys:user:add')}">
    <a href="/user/add" class="btn btn-primary">新增用戶</a>
</c:if>

<c:if test="${permissions.contains('sys:user:delete')}">
    <button class="btn btn-danger" onclick="batchDelete()">批量刪除</button>
</c:if>

模式 2:Thymeleaf 模板判斷(Spring Boot 推薦)

<a th:if="${#sets.contains(session.permissions, 'sys:user:add')}" 
   href="/user/add" class="btn btn-primary">新增用戶</a>

<button th:if="${#sets.contains(session.permissions, 'sys:user:delete')}" 
        class="btn btn-danger" onclick="batchDelete()">批量刪除</button>

模式 3:前後端分離(Vue/React + 權限指令)

後端:登錄成功返回 permissions: ["sys:user:add", "sys:user:delete", ...],前端存入 Vuex/Pinia/Redux/Context。

前端全局指令:

// Vue 3 自定義指令 v-permission
app.directive('permission', {
    mounted(el, binding) {
        const permissions = store.state.user.permissions;
        if (!permissions.includes(binding.value)) {
            el.parentNode?.removeChild(el); // 或 el.style.display = 'none'
        }
    }
});

頁面使用:

<a v-permission="'sys:user:add'" href="/user/add">新增用戶</a>
<button v-permission="'sys:user:delete'" @click="batchDelete">批量刪除</button>

四、進階:菜單級權限與路由守衛

  • 菜單樹構建:後端根據權限過濾菜單節點,返回用戶可見菜單樹,前端遞歸渲染側邊欄。
  • 路由守衛:Vue Router beforeEach 攔截跳轉,檢查目標路由 meta.permission 是否在用戶權限集合中,無權重定向 403 頁。
  • 按鈕級權限:如上指令/標籤控制操作按鈕顯隱,**後端接口仍需二次校驗**,防繞過前端直接調用 API。

五、Session 存儲權限的優缺點與優化

優點缺點優化方案
實現簡單、無額外依賴、讀取極快權限變更需重新登錄生效提供「刷新權限」接口,管理員操作後調用;或定時同步
天然支持集群Session 複製/Redis 存儲增加開銷權限集合體積小(幾 KB),影響可忽略;大權限集可壓縮存儲
無法精細到數據行級權限行級權限需在 Service/SQL 層動態拼接條件,不適合前端判斷

六、總結

「登錄加載 → Session 存儲 → 前端判斷渲染」是權限控制的**最小可行性方案(MVP)**。它以極低複雜度解決 80% 的菜單/按鈕顯隱需求。隨著業務增長,可平滑演進:引入 **Spring Security** 統一認證授權、**RBAC/ABAC 模型** 精細建模、**OAuth2/JWT** 支持微服務無狀態認證、**動態權限刷新** 解決即時生效。但無論架構如何升級,**核心邏輯始終是:認證主體 → 獲取權限集 → 決策點判斷 → 允許/拒絕**。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved