0

i am developing webapp using angular7 and jersey2 frameworks. Java backend runs on tomcat9 and angular on node.js.

I need to call http post method to send nickname and password to backend and get user as response.

angular code:

constructor( private http: HttpClient ) { }

private user : User = null;

private httpOptions = {
  headers: new HttpHeaders({
    'Content-Type': 'application/json'
  })
}

login( nickname : String, password : String ) {
let data = {
     "nickname": nickname,
     "password": password
}
this.http.post<User>(
     "localhost:8080/SRK/rest/users/auth",
     JSON.stringify(data),
     this.httpOptions
).subscribe((user : User) => { console.log(user); this.user = user; });

java rest code:

@Path(value = "users")
public class UserService {

   @POST
   @Path(value = "auth")
   @Consumes(MediaType.APPLICATION_JSON + ";charset=utf-8")
   @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
   public User auth(Map<String, String> nicknameAndPassword) {
       String nickname = nicknameAndPassword.get("nickname");
       String password = nicknameAndPassword.get("password");
       return new UserController.getUserWithNicknameAndPassword(nickname, password);
   }
}

I also tried to add "Access-Control-Allow-Origin": "*" to response header:

@POST
@Path(value = "auth")
@Consumes(MediaType.APPLICATION_JSON + ";charset=utf-8")
@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
public Response getUserWithNicknameAndPassword(Map<String, String> nicknameAndPassword) {
    String nickname = nicknameAndPassword.get("nickname");
    String password = nicknameAndPassword.get("password");
    return Response.ok()
                .entity(new UserController.getUserWithNicknameAndPassword(nickname, password))
                .header("Access-Control-Allow-Origin", "*")
                .header("Access-Control-Allow-Methods", "POST, GET, PUT, UPDATE, OPTIONS")
                .header("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With")
                .build();   
}

but i get this error in browser console when angular login method is called:

 OPTIONS http://localhost:8080/SRK/rest/users/auth 403

 Access to XMLHttpRequest at 'http://localhost:8080/SRK/rest/users/auth' 
 from origin 'http://localhost:4200' has been blocked by CORS policy: 
 Response to preflight request doesn't pass access control check: No 
 'Access-Control-Allow-Origin' header is present on the requested resource.

My WEB-INF/web.xml contains this:

<filter>
    <filter-name>CorsFilter</filter-name>
    <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
    <init-param>
        <param-name>cors.allowed.origins</param-name>
        <param-value>*</param-value>
    </init-param>
    <init-param>
        <param-name>cors.allowed.methods</param-name>
        <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CorsFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

I tried to install "access-control-allow-origin" chrome plugin and run angular app in chrome but the same error.

When i builded angular app to production and added to WebApp folder everything worked fine. I really dont know where is the problem. I appreciate every help.

SOLVED

I created proxy.config.json including this:

{
  "/rest/*":{
    "target": "http://localhost:8080/SRK",
    "secure": false,
    "changeOrigin": true
  }
}

URI in anglar post method is now shorter:

this.http.post<User>(
 /rest/users/auth",
 JSON.stringify(data),
 this.httpOptions
).subscribe((user : User) => { console.log(user); this.user = user; });

And I edited package.json:

"scripts": {
  ...
  "start": "ng serve --proxy-config proxy.config.json",
  ...
},

Now i run angular app by command npm start instead of ng serve.

Thanks for your help.

3 Answers3

0

In C# we do the following. Please check the java equivalent and write in your server side API code. In WebAPIConfig file add the namespace using System.Web.Http.Cors;

Then add the following line of code in Register method: config.EnableCors(new EnableCorsAttribute("http://localhost:8080", headers: "", methods: ""));

This will make the rest API to accept CORS calls.

Niran
  • 1
0

Your server should have something like Access-Control-Allow-Origin: * header in the response.

Adam Genshaft
  • 756
  • 10
  • 22
0

You can workaround it always sending the Access-Control-Allow-Origin header (How to handle CORS using JAX-RS with Jersey) or you can include a server like nginx to perform a reverse proxy for you eliminating the needs for the header

Update:

Sorry for late response, but here you find the nginx documentation: https://docs.nginx.com/?_ga=2.134190344.721047093.1546535765-158692192.1546535765

Also, you need to change the nginx.conf to include something like this:

location /<location_you_wish_for_your_proxy> {
        proxy_pass <your_back_endend_server_location_including_port_and_path>;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
}
pedrohreis
  • 1,030
  • 2
  • 14
  • 33