title: Communication between AngularJS and a Jersey Webservice which are on a different domain. Can't access correct session
body: <p>Lately I've been playing around with AngularJS and Java EE 6. I've build an webservice with Jersey and deployed the project on Glassfish. Because I needed some kind of authentication and an OAuth implementation or an JDBCRealm seemed overkill I decided to just create a session if the user successfully logged in. </p>
  
  <pre><code>@POST
  @Path("/login")
  @Produces({MediaType.APPLICATION_JSON})
  @Consumes({MediaType.APPLICATION_JSON})
  public Response login(LoginDAO loginData, @Context HttpServletRequest req) {
      req.getSession().invalidate();
      loginData.setPassword(PasswordGenerator.hash(loginData.getPassword()));
      User foundUser = database.login(loginData);
      if(foundUser == null) {
          return Response.status(Status.CONFLICT).build();
      }
      req.getSession(true).setAttribute("username", foundUser.getUsername());
      return Response.ok().build();
  }
  
  @GET
  @Path("/ping")
  public Response ping(@Context HttpServletRequest req) {
      if(req.getSession().getAttribute("username") == null) {
          return Response.ok("no session with an username attribute has been set").build();
      }
      return Response.ok(req.getSession(true).getAttribute("username")).build();
  }
  </code></pre>
  
  <p>This seems to work alright, if I post to /login from Postman or from a basic jQuery webpage deployed on glassfish I do get the correct username back and a session has been placed. If I then send a GET request to /ping I do get the username back from which I logged in.</p>
  
  <p>I've an AngularJS application deployed on a node.js webserver which needed to login. Because this server is on another port its on another domain and I had to go through the pain of enabling cors. I did this by building a container response filter which sets the response headers.</p>
  
  <pre><code>public class CrossOriginResourceSharingFilter implements ContainerResponseFilter {
      @Override
      public ContainerResponse filter(ContainerRequest creq, ContainerResponse cresp) {
          cresp.getHttpHeaders().putSingle("Access-Control-Allow-Origin", "http://localhost:8000");
          cresp.getHttpHeaders().putSingle("Access-Control-Allow-Credentials", "true");
          cresp.getHttpHeaders().putSingle("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
          cresp.getHttpHeaders().putSingle("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With");
          return cresp;
      }
  }
  </code></pre>
  
  <p>This did made it possible for me to send different types of HTTP requests from AngularJS to Java EE 6 application deployed on glassfish.</p>
  
  <p>The problem is that when I send a POST request from AngularJS to the /login method, a session is created and I do get my username back. But when I send a GET request to the /ping method I get the "no session with an username attribute has been set" notice. </p>
  
  <p>I believe this has to do with cross domain prevention and that I've to set the withCredentials tag when I send a xhr request. I've been trying to do this in AngularJS but haven't found out how to do this. </p>
  
  <pre><code>function LoginCtrl($scope, $http) {
      $scope.login = function() {
          $http.post("glassfish:otherport/api/login", $scope.credentials).
              success(function(data) {
                  console.log(data);
              }).
              error(function(data, error) {
                  console.log(error);
              });
      };
  };
  </code></pre>
  
  <p>And in another controller:</p>
  
  <pre><code>$scope.getUsername = function() {
      $http.get("glassfish:otherport/api/ping", {}).
          success(function(data) {
              $scope.username = data;
          }).
          error(function() {
              $scope.username = "error";
          })
      }
  </code></pre>
  
  <p>I've tried to set withCredentials is true</p>
  
  <pre><code>$http.defaults.withCredentials = true;
  </code></pre>
  
  <p>This however didn't solve my problem. I also tried to send it with every request in the config parameter but this didn't solve my problem either. </p>