后台跨域造成session失效

1.场景还原

     最近在笔者在springboot中集成token机制发现了一个隐藏bug:“后台实现跨域,前端运用ajax请求后台接口成功回调;一切看似那么顺利,其实不然,session已经后台失效了,每次请求的sessionId不一致,之前缓存在session中的值取出来都为null,怎么回事?瞬间懵逼”,很多人可能问什么跨域?百度哈,不赘述!

2.寻求症结 

①后台实现跨域

 

@RestController
@CrossOrigin
@RequestMapping("/user")
public class UserController extends BaseController {
    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    UserService userService;
    @Autowired
    LoginService loginService;

    @GetMapping(value = "/login")
    public Map getLogin(String loginName,String password){
        String zhangxing = Token.genetateToken();
        session.setAttribute("zhangxing",zhangxing);

        boolean login = false;

        //储存token

        String pwd = loginService.getPassword(loginName);
        Map map = new HashMap();
        if(pwd.equals(password)){
            login = true;
        }
        map.put("login",login);
        map.put("token",zhangxing);
        return map;
    }}

没错,后台就凭

@CrossOrigin

 

一个注解解决了跨域问题。

 

  String zhangxing = Token.genetateToken();
  session.setAttribute("zhangxing",zhangxing);
 

登录并将随机生成的token缓存到session中

 

②前端ajax请求后台接口

 





token




 
用户名:

密 码:

前端登录成功后得到后台的token,并缓存在localStorage中

 

 

 localStorage.setItem("token",data.token);

并且跳转到另一个界面

 

 

window.location.href ="good.html";

③good.html前端代码

 

 




File upload









问题来了?这步前端取出缓存在localStorage的token值

 

 

var token=localStorage.getItem("token");

然后把取出的token传到后台校验接口,代码如下:

 

 

@GetMapping(value = "/getcheck")
public Map getCheck(String tokenStr){
    String token = (String) session.getAttribute("zhangxing");
    boolean check =false;
    //取出token
    System.out.println("取出来的值:"+token);
    if(token != null){
        if(token.equals(tokenStr)){
            check = true;
        }
    }
    Map map = new HashMap();
    map.put("check",check);
    return map;
}

这时发现,无论你怎么挣扎,后台取出session的缓存值始终为null

 

debug之后发现两个controller中的sessionId居然不一致,一脸懵逼!

洗个脸再来,经过逐级排除,笔者定位应该是ajax请求后台跨域接口使session失效,经过一番试错,这个定位果真准!

3.解决方案

只需在ajax中加一个参数设置 xhrFields:{withCredentials:true},完整ajax代码

 

$.ajax({
        type: "get",
        url: "http://localhost:8089/user/login",
        data:{
        "loginName":$("#username").val(),
        "password":$("#pwd").val()
        },
        xhrFields:{withCredentials:true},
        beforeSend: function(XMLHttpRequest){
        // alert(pkinds[0]);
        },
        //请求成功回调
        success: function(data, textStatus){
        alert("进来了");
        alert(data.login);
        alert(data.token);
        if(data.login){

        localStorage.setItem("token",data.token);

        window.location.href ="good.html";

        }

        },
        complete: function(XMLHttpRequest, textStatus){

        },
        error: function(){
        alert("请求网络失败!。。。。。。");
        }
        });

不用质疑,就是这么简单!

 

效果图:

好了,这个问题就over了,我是张星,欢迎加入博主技术讨论群,群号:313145288

 

 

 

你可能感兴趣的:(java,issue)