zoukankan      html  css  js  c++  java
  • Spring Security登录超时,angular ajax请求出错自动跳转至登录页(jQuery也适用)

      公司开发采用Spring Security+AngualerJS框架,在session过期之后,ajax请求会直接出错。本文介绍如何实现出错情况下自动跳转至登录页。

      整体思路是,session过期后,ajax请求返回401 unauthentication错误,前端对$http服务添加拦截器,对401错误进行跳转处理,跳转至登录页。

      由于session过期,需要验证的请求(不论是不是ajax请求)会返回302重定向,我们先配置spring security使之能对ajax请求返回401错误。如下:

      实现自定义的RequestMatcher,当请求是ajax请求即匹配上(angular默认不会带上X-Requested-With,这里通过Accept进行判断,也可以在前端对ajax请求添加X-Requested-With头):

    public static class AjaxRequestMatcher implements RequestMatcher {
        @Override
        public boolean matches(HttpServletRequest request) {
            return "XMLHttpRequest".equals(request.getHeader("X-Requested-With")) ||
                    request.getHeader("Accept") != null && 
                        request.getHeader("Accept").contains("application/json");
        }
    }

      实现自定义的AuthenticationEntryPoint,返回401错误:

    @Component
    public class AjaxAuthenticationEntryPoint implements AuthenticationEntryPoint {
    
        @Override
        public void commence(HttpServletRequest request, HttpServletResponse response,
                AuthenticationException authException) throws IOException, ServletException {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        }
    
    }

      配置错误处理,对ajax请求使用AjaxAuthenticationEntryPoint(

      .exceptionHandling()
            .defaultAuthenticationEntryPointFor(authenticationEntryPoint, new AjaxRequestMatcher())):

        @Autowired
        private AuthenticationEntryPoint authenticationEntryPoint;
        
        protected void configure(HttpSecurity http) throws Exception {
            http
                .headers()
                    .cacheControl()
                    .and()
                .authorizeRequests()
                    .antMatchers(
                        "/login",
                        "/css/**",
                        "/img/**",
                        "/js/**",
                        "/partial/**",
                        "/script/**",
                        "/upload/**",
                        "/plugin/**").permitAll()
                    .antMatchers("/**")
                    .authenticated()
                    .and()
                .formLogin()
                    .loginPage("/login")
                    .permitAll()
                    .defaultSuccessUrl("/app.html", true)
                    .and()
                .logout()
                    .logoutUrl("/logout")
                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                    .logoutSuccessUrl("/login")
                    .and()
                .exceptionHandling()
                    .defaultAuthenticationEntryPointFor(authenticationEntryPoint, new AjaxRequestMatcher())
                    .and()
                .csrf().disable();
        }

      前端,添加拦截器:

    angular.module('app', [])
    .config(function($httpProvider) {
        $httpProvider.interceptors.push(function($q, $window) {
              return {
                // optional method
                'request': function(config) {
                  // do something on success
                  return config;
                },
                // optional method
               'requestError': function(rejection) {
                  // do something on error
                  if (canRecover(rejection)) {
                    return responseOrNewPromise
                  }
                  return $q.reject(rejection);
                },
                // optional method
                'response': function(response) {
                  // do something on success
                  return response;
                },
                // optional method
               'responseError': function(rejection) {
                  // do something on error
                  if (rejection.status === 401) {
    //                return responseOrNewPromise
                      console.log('401');
                      $window.location.href = 'login?expired';
                  }
                  return $q.reject(rejection);
                }
              };
            });
    });
  • 相关阅读:
    微信小程序tab(swiper)切换
    微信小程序如何动态增删class类名
    Vi (Unix及Linux系统下标准的编辑器)VIM (Unix及类Unix系统文本编辑器)
    js 阻止事件冒泡和默认行为 preventDefault、stopPropagation、return false
    H5中的touch事件
    CSS3 Gradient 渐变
    CSS3动画属性Transform解读
    你所不知的 CSS ::before 和 ::after 伪元素用法
    javascript移动设备Web开发中对touch事件的封装实例
    那些过目不忘的H5页面
  • 原文地址:https://www.cnblogs.com/phoenix-smile/p/5681271.html
Copyright © 2011-2022 走看看