在我的后端,我在登录后对用户进行身份验证,然后将经过身份验证的 session 存储在服务器上。然后在每个用户的请求之后,我检查与请求关联的 session 是否存储为已验证。问题是,当我使用 JavaScript 请求时,每次我向用 Java 编写的服务器发送内容时,都会使用一个新的 HTTP session 。
当我使用 Postman 时一切正常,因为它通过许多请求存储 session 。
//Here is authentication on server side - it works fine
@CrossOrigin
@RequestMapping(value= "/login", method = RequestMethod.POST)
public @ResponseBody String login(@RequestBody Account retrievedAccount,
HttpServletRequest httpServletRequest) {
if (retrievedAccount != null) {
Account account =
accountDAO.getAccountByLogin(retrievedAccount.getLogin());
if (account != null &&
account.getPassword().equals(retrievedAccount.getPassword())) {
this.registeredSessionsContainer.add(httpServletRequest.getSession());
return new ResponseEntity(HttpStatus.OK).toString();
} else {
return new ResponseEntity(HttpStatus.UNAUTHORIZED).toString();
}
} else {
return new ResponseEntity(HttpStatus.UNAUTHORIZED).toString();
}
}
这是检查 session 是否已通过身份验证的简单方法:
@CrossOrigin
@RequestMapping(value= "/checkLogon", method = RequestMethod.GET)
public @ResponseBody String checkLogon(HttpServletRequest
httpServletRequest) {
if(this.registeredSessionsContainer.
contains(httpServletRequest.getSession()))
return new ResponseEntity(HttpStatus.OK).toString();
} else {
return new ResponseEntity(HttpStatus.UNAUTHORIZED).toString();
}
这是我在前端 JavaScript 中登录服务的方式:
performLoggingToService(){
var login = document.getElementById("loginField").value;
var password = document.getElementById("passwordField").value;
var url = "http://localhost:8080/mvc1/login";
var method = "POST";
var crendentialsObject = { "login": login, "password": password };
var crendentialsObjectJSON = JSON.stringify(crendentialsObject);
console.log(crendentialsObjectJSON);
var req = new XMLHttpRequest();
req.open("POST", url, true);
req.setRequestHeader("Content-Type", "application/json");
req.send(crendentialsObjectJSON);
//console.log("Is this undefined: "+(loginComponent==undefined));
var props = this.props;
var thisObjectPointer = this;
req.onload = function (e,thisObject=thisObjectPointer) {
var status = req.status; // HTTP response status, e.g., 200 for "200 OK"
var data = req.responseText; // Returned data
if(data.includes("200 OK")){
console.log("Checking LOGON STATE METHOD#2: ");
thisObject.props.refreshLogonStateInMainBand(login);
} else {
// inform user about wrong credentials
}
}
}
然后当我执行检查我是否已经登录一个地址/checkLogon 时,我使用:
checkLogonState(currentUserName) {
console.log("CheckLogonState CALLED!");
var url = "http://localhost:8080/mvc1/checkLogon";
var method = "GET";
var req = new XMLHttpRequest();
var loginData;
req.overrideMimeType("application/json");
req.open('GET', url, true);
req.onload = function() {
}
req.send();
req.onreadystatechange=(e)=>{
if(req.readyState === 4 && req.responseText.length>0) {
if(req.responseText.includes("200 OK")){
console.log("Authenticated!!!");
this.changeMainComponentStateToLogin();
this.currentUserName = currentUserName;
this.oneTimeLogonCheckAction=false;
} else {
console.log("Not logged in!!!")
this.changeMainComponentStateToIdle();
this.currentUserName=undefined;
this.oneTimeLogonCheckAction=true;
}
this.forceUpdate();
}
}
}
如您所料,responseTest 包含 404 Unauthorized 而不是 200 OK。
我在 InternetExplorer、Microsoft Edge 和 Chrome 上试过了。他们都没有重用 session 。
在我的每个请求之后,服务器端的控制台显示请求是从其他 session 发送的 - 每个请求都在一个新 session 中。 我想知道如果我通过许多请求使用一个相同的浏览器窗口,我该如何使用相同的 session 。
最佳答案
将所有 XMLHttpRequest
的 withCredentials
设置为 true
,
var req = new XMLHttpRequest();
req.withCredentials = true;
req.open("POST", url, true);
req.setRequestHeader("Content-Type", "application/json");
req.send(crendentialsObjectJSON);
将有助于在通话中保持 session 。
在服务器端将此添加到所有 Controller 以解决 cors 问题,
@CrossOrigin(origins = ["http://localhost:3000"], allowCredentials = "true")
关于javascript - 通过许多请求在 javascript 中使用相同的 http session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56219292/