核心流程
- 登錄成功 → 查詢數據庫獲取角色/權限 → 存入
Session。
- 每請求 → 過濾器/攔截器讀取
Session → 根據 URL/註解判斷權限 → 放行/重定向登錄/403。
數據庫設計
CREATE TABLE user (id PK, username, password_hash, role_id FK);
CREATE TABLE role (id PK, name); -- admin, teacher, student
CREATE TABLE permission (id PK, url_pattern, method);
CREATE TABLE role_permission (role_id, permission_id);
Java 代碼實現 (Spring MVC 為例)
// 1. 登錄 Controller
@PostMapping("/login")
public String login(@RequestParam String u, @RequestParam String p, HttpSession session) {
User user = userService.auth(u, p);
if (user != null) {
session.setAttribute("user", user);
session.setAttribute("permissions", permissionService.getByRole(user.getRoleId()));
return "redirect:/index";
}
return "login";
}
// 2. 權限過濾器
@Component
public class AuthFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) {
String uri = req.getRequestURI();
HttpSession session = req.getSession(false);
if (isPublic(uri) || (session != null && hasPermission(session, uri))) {
chain.doFilter(req, res);
} else {
res.sendRedirect("/login?redirect=" + URLEncoder.encode(uri, "UTF-8"));
}
}
private boolean hasPermission(HttpSession session, String uri) {
Set perms = (Set) session.getAttribute("permissions");
return perms != null && perms.stream().anyMatch(p -> AntPathMatcher.match(p, uri));
}
}
最佳實踐建議
- 使用成熟框架:Spring Security、Apache Shiro、Sa-Token,已實現上述邏輯並支持註解式權限 (
@RequiresRoles、@RequiresPermissions)。
- Session 集群化:Redis + Spring Session,支持多實例部署。
- 敏感操作二次驗證:修改密碼、刪除數據需重新輸入密碼/驗證碼。