Angular应用实现系统锁屏/注销时自动跳转登录页方案咨询
实现方案:系统锁屏/注销时自动跳转登录页
前端(AngularJS)实现思路
核心是利用HTML5 Page Visibility API检测页面是否进入隐藏状态(系统锁屏/切换到全屏应用时会触发该状态),结合AngularJS的会话管理逻辑主动触发注销流程。
- 监听页面可见性变化事件:
在AngularJS的run块中注册visibilitychange事件监听器,当页面状态变为hidden时执行注销操作:angular.module('yourApp').run(['$rootScope', '$location', '$http', function($rootScope, $location, $http) { // 兼容不同浏览器的API前缀(主流浏览器已支持标准写法) var hiddenProperty = 'hidden' in document ? 'hidden' : 'webkitHidden' in document ? 'webkitHidden' : 'mozHidden' in document ? 'mozHidden' : null; var visibilityChangeEvent = hiddenProperty.replace(/hidden/i, 'visibilitychange'); document.addEventListener(visibilityChangeEvent, function() { if (document[hiddenProperty]) { // 页面隐藏,发起注销请求 $http.post('/api/logout') .then(function() { // 清除前端会话存储(根据实际存储方式调整,比如cookieStore) localStorage.removeItem('authToken'); // 跳转登录页 $location.path('/login'); }) .catch(function() { // 请求失败时强制清除前端状态并跳转 localStorage.removeItem('authToken'); $location.path('/login'); }); } }); }]); - 防抖优化:避免频繁切换标签页误触发,可添加时间判断,仅当页面隐藏超过2秒才执行注销:
var lastHiddenTime; document.addEventListener(visibilityChangeEvent, function() { if (document[hiddenProperty]) { lastHiddenTime = Date.now(); } else { // 解锁时检查会话状态,失效则直接跳转 if (!localStorage.getItem('authToken')) { $location.path('/login'); } } // 延迟执行,确认是长期隐藏(锁屏)而非短暂切窗口 setTimeout(function() { if (document[hiddenProperty] && Date.now() - lastHiddenTime > 2000) { // 执行注销逻辑 $http.post('/api/logout').finally(function() { localStorage.removeItem('authToken'); $location.path('/login'); }); } }, 2000); });
后端(Spring MVC)配合方案
后端主要负责安全销毁会话,并确保未认证请求被拦截处理:
- 实现注销接口:
在Spring Controller中编写注销接口,主动销毁当前会话:@Controller @RequestMapping("/api") public class AuthController { @PostMapping("/logout") public ResponseEntity<Void> logout(HttpServletRequest request) { // 销毁当前会话 request.getSession().invalidate(); return ResponseEntity.ok().build(); } } - 配置请求拦截器:
自定义拦截器检查会话有效性,未登录或会话失效时返回401状态码,前端收到后跳转登录:
在Spring配置中注册拦截器:public class AuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpSession session = request.getSession(false); // 检查会话中是否存在用户标识(根据你的认证逻辑调整) if (session == null || session.getAttribute("currentUser") == null) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return false; } return true; } }@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new AuthInterceptor()) .addPathPatterns("/api/**") // 拦截需要认证的API .excludePathPatterns("/api/login", "/api/logout"); // 排除登录、注销接口 } } - (可选)使用Spring Security简化管理:
若使用Spring Security,可直接配置logout处理器和会话过期策略,自动处理会话销毁:@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/login", "/api/login").permitAll() .anyRequest().authenticated() .and() .logout() .logoutUrl("/api/logout") .invalidateHttpSession(true) .deleteCookies("JSESSIONID") .permitAll(); } }
注意事项
- 系统注销时,操作系统会直接终止浏览器进程或失效会话,此时前端可能来不及触发请求,但后端会话已销毁,用户再次打开应用时会自动跳转登录。
- 部分浏览器在最小化窗口时也会触发
hidden状态,可通过防抖逻辑区分短暂切窗口和锁屏场景。
内容的提问来源于stack exchange,提问作者Shubham Pratap Singh
相关产品推荐
相关产品推荐

