Springboot前后端分离中,后端拦截器拦截后,前端没有对应的返回码可以判断


项目登录流程如下

       用户进入前端登录界面,输入账号密码等,输入完成之后前端发送请求到后端(拦截器不会拦截登录请求),后端验证账号密码等成功之后生成Token并存储到数据库,数据库中包含该Token过期时间,然后返回生成的Token到前端。

       前端收到Token,表示登录成功,把这个Token存储到浏览器Cookie中。然后跳转到用户中心页面,用户中心页面从浏览器Cookie中扣出Token,跟随请求用户数据接口一起带到后端。

       后端通过拦截器拦截到这个请求,去判断这个Token是否有效,有效就放过去做他该做的事情,无效就抛出异常。

跨域配置

先说一下这个前后分离的项目,已经配置过跨域这些问题。我这里后端配置的方式如下:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {    
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
                .maxAge(3600)
                .allowCredentials(true);
    }
}

前端每次发送请求也都有在ajax里面设置xhrFields:{withCredentials: true}属性。

拦截器代码

@Component
public class LoginInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //从header中获取token
        String token = request.getHeader("token");
        //token为空
        if(StringUtils.isBlank(token)){
            throw new XjxccException("登录信息不存在,请重新登录", 601);
        }

        //查询token信息
        TbUserToken tbToken = tokenService.queryByToken(token);
        if(tbToken == null || tbToken.getExpireTime().getTime() < System.currentTimeMillis()){
            throw new XjxccException("登录信息已失效,请重新登录", 602);
        }

        return true;
    }
}

问题

现在的情况是,如果Token正常就没问题,如果Token失效了,前端发送的请求就会提示跨域问题,可是该项目已经配置过跨域问题了。既然又提示跨域问题,那我们修改代码如下:

@Component
public class LoginInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //从header中获取token
        String token = request.getHeader("token");
        //token为空
        if(StringUtils.isBlank(token)){
            setCorsMappings(request, response);
            throw new XjxccException("登录信息不存在,请重新登录", 601);
        }

        //查询token信息
        TbUserToken tbToken = tokenService.queryByToken(token);
        if(tbToken == null || tbToken.getExpireTime().getTime() < System.currentTimeMillis()){
            setCorsMappings(request, response);
            throw new XjxccException("登录信息已失效,请重新登录", 602);
        }

        return true;
    }

    private void setCorsMappings(HttpServletRequest request, HttpServletResponse response){
        String origin = request.getHeader("Origin");
        response.setHeader("Access-Control-Allow-Origin", origin);
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Authorization");
        response.setHeader("Access-Control-Allow-Credentials", "true");
    }
}

 这样修改之后,如果Token无效,前端发送的请求就不会提示跨域问题。而且也可以在ajax的success方法中根据错误码(601/602)做不同的判断,代码如下:

$.ajax({
    type: "POST",
    url: "请求用户信息接口",
    xhrFields:{withCredentials: true},
    headers: {token: vm.token},
    contentType: 'application/json',  
    success: function(result){
                //如果是token无效
        if(result.code == 601 || result.code == 602){
            layer.msg(result.msg + "<br>稍后为您自动跳转到登录页面");
            window.setInterval(function (){
                window.location.href = "user-login.html";
            },1500);
        }else if(判断用户信息接口返回的code){
                    ...
                }
    },error: function(){
        layer.msg("系统异常");
    }
});

下面附上上面代码中的XjxccException类:

/**
 * <p>Title: XjxccException.java</p>  
 * <p>Description: 自定义异常</p>  
 * <p>Copyright: Copyright (c) 2018</p>
 *  
 * @email lgqxjxcc@163.com 
 * @author liguoqing  
 * @date 2018年10月21日  
 * @version 1.0
 */
public class XjxccException extends RuntimeException {
    private static final long serialVersionUID = 1L;
    
    private String msg;
    private int code = 500;
    
    public XjxccException(String msg) {
        super(msg);
        this.msg = msg;
    }
    public XjxccException(String msg, Throwable e) {
        super(msg, e);
        this.msg = msg;
    }
    public XjxccException(String msg, int code) {
        super(msg);
        this.msg = msg;
        this.code = code;
    }
    public XjxccException(String msg, int code, Throwable e) {
        super(msg, e);
        this.code = code;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
}

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM