Search code examples
javascriptjavahttpsession-management

Utilize same http session in javascript through many requests


In my backend I authenticate user once inlogging and then store the authenticated sessions at the server. Then after each user's request i check if the session associated with a request is stored as authenticated. The problem is that when I use JavaScript requests a new HTTP session is used each time i send something to my server written in Java.

When I use Postman everything is okay because it stores session through many requests.

//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();
 }

 }

Here is a simple way to check if a session is already authenticated:

 @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();
    }

Here is how i login to service in my frontend 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
  }
  }

  }

An then when i perform check if i am already logged in one address /checkLogon I use:

 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();
 }
 }

 }

As you may expect responseTest includes 404 Unauthorized not 200 OK.

I tried it on InternetExplorer, Microsoft Edge and Chrome. None of them reuses session.

After each of my requests console on server side shows that the requests are sent from other sessions - each request in a new session. I would like to get to know how can I use same session if i use one the same browser window through many requests.


Solution

  • Set withCredentials to true for all XMLHttpRequest,

      var req = new XMLHttpRequest();
      req.withCredentials = true;
      req.open("POST", url, true);
      req.setRequestHeader("Content-Type", "application/json");
      req.send(crendentialsObjectJSON);
    

    will help to persist the session across calls.

    At server side add this to all your controllers to solve cors issues,

    @CrossOrigin(origins = ["http://localhost:3000"], allowCredentials = "true")