前后端分离项目开发过程中,因为服务部署和h5页面联调接口会存在跨域问题,导致服务端在认证session的时候h5页面每次请求sessionID都会改变,无法进行登录认证功能联调。
于是查资料发现一些问题,记录下来。
浏览器第一次请求服务器,服务器会随机生成一个唯一sessionID,然后返回给浏览器,浏览器将这个sessionID保存到cookie。
正常非跨域请求,以后浏览器再次请求服务器,会将这个sessionID通过cookie发送给服务器,服务器接收到sessionID,这样sessionID就不会变化。
如果H5页面和后端服务放到同一个Tomcat就没有跨域问题了,所以sessionID不变。
因为跨源请求不提供凭据(cookie、HTTP认证及客户端SSL证明等)。也就是每次请求不携带cookie中数据。
所以,每次请求服务器都会重新生成一个sessionID返回给浏览器,这样每次浏览器请求sessionID都会变化。
要让跨域请求提供凭据,可以在ajax请求中通过将withCredentials属性设置为true,指定某个请求应该发送凭据。
这样每次跨域请求都会将cookie中的sessionID发送给服务器,sessionID就不会再改变了。
下面是解决跨域问题部分前后端代码。
前端代码:
<!DOCTYPE html> <html lang="zh-cn"> <head> <title>session-test</title> <script src="jquery-3.3.1.min.js" type="text/javascript"></script> </head> <body> <h1>session</h1> <script> $(document).ready(function() { $.ajax({ url:"http://localhost:8080/ssm-example/getSession", xhrFields: { withCredentials: true }, success:function(data){ alert("sessionID = " + data); } }); }); </script> </body> </html>
后端代码:
package com.ssm.example.controller; import javax.servlet.http.HttpSession; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class UserController { @RequestMapping("/getSession") @ResponseBody @CrossOrigin() public String getSession(HttpSession session) { String sessionID = session.getId(); System.out.println(sessionID); return sessionID; } }