一、spring boot 后台

  1. 拦截器

spring boot 推荐使用拦截器(拦截器是记忆web框架,过滤器是基于servlet 容器)

实现HandlerInterceptor接口,处理拦截器的相应操作

import com.gsww.human.entity.HumanUser;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * @author: TuoPeng
 * @Date: 2020/3/12 Time: 10:46
 * 拦截器
 */
public class AccessInterceptor implements HandlerInterceptor {

    /**
     * 在请求处理之前进行调用(controller方法调用之前)
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();

        HumanUser humanUser = (HumanUser)session.getAttribute("humanUser");
        if (humanUser == null){
            response.setStatus(401);
        }
        return true;
    }

    /**
     * 在请求处理之后进行调用,但是在试图渲染之前(Controller方法调用之后)
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }

    /**
     * 在整个请求结束之后被调用,也就是DispatcherServlet 渲染了对应视图之后执行(主要是用于资源的清理工作)
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }
}

在拦截器中配置需要拦截的接口地址(如需要登录之后才能调用的接口)接口地址拦截和不需要拦截的接口(如验证码接口)

@Override
    public void addInterceptors(InterceptorRegistry registry){
        InterceptorRegistration registration = registry.addInterceptor(new AccessInterceptor());
        registration.addPathPatterns("/**");
        registration.excludePathPatterns("/kaptcha/defaultKaptcha","/yhjk/humanUser/login");
    }
  1. 遇到问题
    1)登录问题:
    问题描述:登录过期后(sesssion过期),前端调用接口是请求返回failed,session与前一次请求的session不一致(ps:判断依据为两次的sessionId不一致)。
    问题成因:由于前端使用了vue(iview框架),所以会遇到跨域的问题,起初使用的是注解的方式进行跨域处理,但是同时也会遇到一个问题,那就是当调用的接口被拦截时,无法调用的接口从而导致跨域失败,http请求返回failed,前台无法判读接口是因为接口逻辑原因出现问题,还是因为根本无法调用到接口出现问题。

    解决方案:重新配置全局的跨域,不只是在调用接口时进行跨域
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;


/**
 * @author: TuoPeng
 * @Date: 2020/3/12 Time: 11:01
 */
@Configuration
public class LoginConfig implements WebMvcConfigurer {

    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        // 设置允许跨域请求的域名
        config.addAllowedOrigin("*");
        // 是否允许证书 不再默认开启
        // config.setAllowCredentials(true);
        // 设置允许的方法
        config.addAllowedMethod("*");
        // 允许任何头
        config.addAllowedHeader("*");
        config.addExposedHeader("token");
        config.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);
        return new CorsFilter(configSource);
    } 
}

问题二、浏览器cookie的丢失问题
问题描述:用于谷歌浏览器的问题导致用户登录时,cookie的丢失。在配置登录拦截,使用户登录停留在登录页面

A cookie associated with a cross-site resource at http://127.0.0.1/ was set without the `SameSite` attribute. A future release of Chrome will only deliver cookies with cross-site requests if they are set with `SameSite=None` and `Secure`. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/563352162218803

解决方案:前往chrome://flags/ 设置SameSite by default cookies和Cookies without SameSite must be secure为disabled
详细解决办法见:SameSite Cookie 变更:您需要了解的都在这里

二、 vue

对于登录页面的html代码不在赘述,百度的页面应该有很多
路由拦截
请求拦截

axios.interceptors.request.use(

    config => {
        let token = getStore('token')
        if (token && config.url.indexOf('oauth') < 0) {
            config.headers.Authorization = token;
        }
        if (config.url.indexOf('oauth') > 0) {
            // 登陆认证 格式为表单形式提交
            config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
        }
        return config;
    },
    err => {
        return Promise.reject(err);
    }
);

响应拦截

axios.interceptors.response.use(
    response => {
        return response;
    },
    error => {
        if (error.response) {
            switch (error.response.status) {
                case 401:
                    debugger
                    // 401 清除token信息并跳转到登录页面
                    // Message.error('登录超时,请重新登录');
                    // debugger
                    store.commit('logout');
                    // 只有在当前路由不是登录页面才跳转
                    router.currentRoute.path !== "/" &&
                        router.replace({
                            path: "/",
                            query: {
                                redirect: router.currentRoute.path
                            }
                        });
            }
        }
        return Promise.reject(error.response.data);
    }
);