在我的后端,我一旦登录便对用户进行身份验证,然后将经过身份验证的会话存储在服务器上。然后,在每个用户的请求之后,我检查与请求关联的会话是否存储为已认证。问题是,当我使用JavaScript请求时,每次将某些内容发送到用Java编写的服务器时,都会使用一个新的HTTP会话。
当我使用Postman时,一切正常,因为它通过许多请求存储会话。
//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();
}
}
这是检查会话是否已通过身份验证的简单方法:
@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未经授权,而不是200 OK。
我在InternetExplorer,Microsoft Edge和Chrome上尝试过。他们都没有重用会话。
在服务器端我的每个请求控制台显示请求是从其他会话发送的之后-每个请求都在一个新会话中。 我想知道如果通过多个请求使用同一浏览器窗口,该如何使用同一会话。
答案 0 :(得分:0)
将所有withCredentials
的{{1}}设置为true
,
XMLHttpRequest
将有助于在通话中保持会话状态。
在服务器端将此添加到您的所有控制器中以解决cors问题,
var req = new XMLHttpRequest();
req.withCredentials = true;
req.open("POST", url, true);
req.setRequestHeader("Content-Type", "application/json");
req.send(crendentialsObjectJSON);