在Web應用中,登錄攔截是一個常見的需求。通過攔截未登錄用戶的請求,可以保護系統的安全性,防止未授權用戶訪問敏感資源。Spring Boot 提供了多種方式來實現登錄攔截,其中一種常見的方式是通過 ThreadLocal
來實現。
ThreadLocal
是 Java 中的一個線程局部變量工具類。它為每個線程提供了一個獨立的變量副本,每個線程都可以獨立地改變自己的副本,而不會影響其他線程的副本。ThreadLocal
通常用于在多線程環境下保存線程的上下文信息。
在 Web 應用中,ThreadLocal
可以用來保存當前登錄用戶的信息,從而在請求處理過程中隨時獲取用戶信息。
首先,我們需要定義一個 ThreadLocal
變量來保存當前登錄用戶的信息。通常,我們會將用戶信息封裝在一個 User
對象中。
public class UserContext {
private static final ThreadLocal<User> currentUser = new ThreadLocal<>();
public static void setCurrentUser(User user) {
currentUser.set(user);
}
public static User getCurrentUser() {
return currentUser.get();
}
public static void clear() {
currentUser.remove();
}
}
接下來,我們需要實現一個登錄攔截器。攔截器會在請求到達控制器之前執行,我們可以在這里檢查用戶是否已經登錄。
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 從請求中獲取用戶信息(例如從Session或Token中獲?。? User user = getUserFromRequest(request);
if (user == null) {
// 用戶未登錄,返回未授權錯誤
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "未登錄");
return false;
}
// 將用戶信息保存到ThreadLocal中
UserContext.setCurrentUser(user);
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 請求完成后,清除ThreadLocal中的用戶信息
UserContext.clear();
}
private User getUserFromRequest(HttpServletRequest request) {
// 實現從請求中獲取用戶信息的邏輯
// 例如從Session中獲取用戶信息
return (User) request.getSession().getAttribute("user");
}
}
最后,我們需要將攔截器注冊到 Spring Boot 的攔截器鏈中。
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/**") // 攔截所有請求
.excludePathPatterns("/login", "/register"); // 排除登錄和注冊頁面
}
}
在控制器中,我們可以通過 UserContext.getCurrentUser()
來獲取當前登錄用戶的信息。
@RestController
public class UserController {
@GetMapping("/profile")
public ResponseEntity<User> getProfile() {
User user = UserContext.getCurrentUser();
if (user == null) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
return ResponseEntity.ok(user);
}
}
通過 ThreadLocal
實現登錄攔截是一種簡單而有效的方式。它允許我們在請求處理過程中隨時獲取當前登錄用戶的信息,并且不會影響其他線程的請求處理。在實際開發中,我們可以根據具體需求對攔截器進行擴展,例如支持 Token 驗證、權限控制等。
需要注意的是,ThreadLocal
的使用需要謹慎,確保在請求完成后及時清理線程局部變量,避免內存泄漏問題。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。