-1

I made a simple REST API interface with Java Jersey on http://localhost:8093, but when I send XmlHTTPRequest via javascript via different services ( i.g. http://localhost:80/ ) CORS are not allowed. Here my very easy snippet code:

//---------------------------------------------Application.java:

import javax.ws.rs.ApplicationPath;

import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@ApplicationPath("rest")
public class Application extends ResourceConfig {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);    
        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            public void run() {
            }
        }));    
    }
    
    public Application() {
        register(new UserAPI());
    }
}

//---------------------------------------------UserAPI.java:

import java.text.ParseException;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;


@Consumes("application/json")
@Produces("application/json")
@Path("user")
public class UserAPI {
    @POST
    @Path("add")    
    public void addUser(UserBean ub) throws ParseException, UserException, NullPasswordException{        
        Logger mongoLogger = Logger.getLogger( "org.mongodb.driver" );
        mongoLogger.setLevel(Level.SEVERE);
        
        User u= new User(ub.getUsername(), ub.getRole());
        (new MongoDataManager()).addUser(u);
}
    
    @POST
    @Path("edit")    
    public void editUser(UserBean ub) throws ParseException, UserException, NullPasswordException{        
        Logger mongoLogger = Logger.getLogger( "org.mongodb.driver" );
        mongoLogger.setLevel(Level.SEVERE);
        
        User u= new User(ub.getUsername(), ub.getPassword());
        u.setRole(Role.valueOf(ub.getRole()));
        u.setPasswordLastUpdate(new Date());
        
        (new MongoDataManager()).editUser(u);
        
}
    
    
    @POST
    @Path("delete")    
    public void deleteUser(UserBean ub) throws ParseException {        

        Logger mongoLogger = Logger.getLogger( "org.mongodb.driver" );
        mongoLogger.setLevel(Level.SEVERE);
        
        
        
        (new MongoDataManager()).deleteUser(ub.getUsername());    
         }
}

//---------------------------------------------UserBean.java:

public class UserBean {
    private String         username, password, temppass;
    private String    residence;
    private String        role;
    private String        password_lastupdate;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getTemppass() {
        return temppass;
    }
    public void setTemppass(String temppass) {
        this.temppass = temppass;
    }
    public String getResidence() {
        return residence;
    }
    public void setResidence(String residence) {
        this.residence = residence;
    }
    public String getRole() {
        return role;
    }
    public void setRole(String role) {
        this.role = role;
    }
    public String getPassword_lastupdate() {
        return password_lastupdate;
    }
    public void setPassword_lastupdate(String password_lastupdate) {
        this.password_lastupdate = password_lastupdate;
    }
    
}

//--------------------------------------------- Javascript function:

 function create() {
    event.preventDefault()           
    let isNew = document.getElementById("createNuovoUser").checked;
    console.log(isNew)       
let url;
let request = new XMLHttpRequest();   // new HttpRequest instance


if (isNew){
    url = 'http://localhost:8093/rest/user/delete'
    request.open("POST", url, true);
    request.setRequestHeader("content-type", "application/json");

    request.onreadystatechange = function() {
        if (this.readyState === 4) {
            document.getElementById("createTextArea").value = username + "\n";
            alert("User eliminato");
        }
    };
     let username = document.getElementById("username").value 
     let role = document.getElementById("role").value
    request.send(JSON.stringify({"username": username}));
} else{
    url = 'http://localhost:8093/rest/user/add'
    request.open("POST", url, true);
    request.setRequestHeader("content-type", "application/json");

    request.onreadystatechange = function() {
        if (this.readyState === 4) {
            document.getElementById("createTextArea").value = username + "\n" + role;
            alert("User cereato");

        }
    };
    
   let username = document.getElementById("username").value
   let role = document.getElementById("role").value
    request.send(JSON.stringify({"username": username, "role": role}));

} }

Any suggest or solution is appreciated thanks

ricciuto99
  • 21
  • 3
  • 1
    your server code needs to set some CORS headers - [learn cors in 6 minutes](https://www.youtube.com/watch?v=PNtFSVU-YTI) – Jaromanda X Jun 19 '21 at 12:28
  • As the javascript you are executing is served from a different port, it is considered to be a different origin. When you send an XHR or ajax request (behind the knowledge of the user) the browser will apply CORS policy. You need to setup CORS headers in the server allowing access from the other port. Yoy can find more on this in the MDN pages https://developer.mozilla.org/es/docs/Web/HTTP/CORS – Juan Jun 19 '21 at 12:43

1 Answers1

0

This is a normal issue with jersey. You just need to add a request filter that allows the 'Option' requests

look at this topic How to handle CORS using JAX-RS with Jersey

In practice, you need to implement a class to extend server config

import java.io.IOException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;

@Provider
public class CORSFilter implements ContainerResponseFilter {

@Override
public void filter(ContainerRequestContext request,
        ContainerResponseContext response) throws IOException {
    response.getHeaders().add("Access-Control-Allow-Origin", "*");
    response.getHeaders().add("Access-Control-Allow-Headers",
            "CSRF-Token, X-Requested-By, Authorization, Content-Type");
    response.getHeaders().add("Access-Control-Allow-Credentials", "true");
    response.getHeaders().add("Access-Control-Allow-Methods",
            "GET, POST, PUT, DELETE, OPTIONS, HEAD");
}

}

then explicitly select it with this code in the server class

final ResourceConfig resourceConfig = new ResourceConfig();
resourceConfig.register(new CORSFilter());
Alex Longo
  • 11
  • 3
  • I have tried to follow many guides but the result is always negative. Could you give me a solution for my code? – ricciuto99 Jun 19 '21 at 13:23