javaangularfrontendbackendhttp-delete

Cors blocking HTTP delete Method


I am getting a CORS error when I try to use my HTTP Delete method. My Frontend is Angular-ionic and my Server is a Java server. Both are self-made.

I tried to disable CORS in the Browser, by doing so I managed the Request to work and the Error to disappear. Although that's fine, my goal is to make it work every time for EVERY user.

Here is my Code with a bit of Background:

      console.log('User Management Service Delete User()');
      const myParams = new HttpParams().set('id', this.cookieService.get('AccessToken'));
      console.log(myParams);
      return this.http.delete(this.endpoint + 'users/delete', { params: myParams});
    }

The code above is my FRONTEND (clientside) code. I am simply trying to delete a user.

    public int serveUserDelete(HTTPServer.Request req, HTTPServer.Response resp) throws IOException {
        Map<String, String> params = req.getParams();
        String response;
        String paramvalue;
        String  accessToken;    
        
        resp.getHeaders().add("Content-Type", "application/json");
        resp.getHeaders().add("Access-Control-Allow-Origin", "*");
        resp.getHeaders().add("Access-Control-Allow-Headers", "*");
        resp.getHeaders().add("Access-Control-Allow-Credentials", "true");
        resp.getHeaders().add("id", "*");
        resp.getHeaders().add("Access-Control-Allow-Methods", "OPTIONS, DELETE, POST, GET, PATCH, PUT");
        
        response = "";
        //Id aus dem Parameter auslesen
        if (params.containsKey("id")) {
            //es gibt einen Parameter id. Suche den Wertd dazu
            accessToken = params.get("id");
            System.out.println(accessToken);
            
        } else {
            accessToken = null;
        }
        response = um.userDelete(accessToken);
        resp.send(200, response);
        return 0;
    }

The Code above now, is my Java server. The headers were added cause of trial and error.

Here the error I am getting:

Access to XMLHttpRequest at 'http://localhost:8080/umyServerUrl/users/delete?id=u@Yy0NZPLx%266HxYNF%23tv' 
from origin 'http://localhost:8100' 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.

threw testing (with disabled browser cors etc.) I found out that the methods on my server work just fine.

Here you can see my "PARAMS" and the Observable of my delete Request printed in the Console:

HttpParams 
{updates: Array(1), 
cloneFrom: HttpParams, 
encoder: HttpUrlEncodingCodec, 
map: null}
cloneFrom: 
nullencoder: 
HttpUrlEncodingCodec {}[[Prototype]]:
Objectconstructor: class
HttpUrlEncodingCodecdecodeKey: ƒ 
decodeKey(key)decodeValue: ƒ 
decodeValue(value)encodeKey: ƒ 
encodeKey(key)encodeValue: ƒ 
encodeValue(value)[[Prototype]]: 
Objectmap: 
Map(1)[[Entries]]0: {"id" => Array(1)}
key: "id" value: ['hTxYusBwuB7pbUUCkW9E']size: 1[[Prototype]]:
Mapupdates: null[[Prototype]]: 
Object
user-management.service.ts:35 

**Oberservabel:**

Observable {_isScalar: false, source: Observable, 
operator: MapOperator}
operator: MapOperator
project: res => res.body
length: 1
name: ""
arguments: (...)
caller: (...)
[[FunctionLocation]]: http.mjs:1300
[[Prototype]]: ƒ ()
[[Scopes]]: Scopes[2]
thisArg: undefined
[[Prototype]]: Object
call: ƒ call(subscriber, source)
constructor: class MapOperator
[[Prototype]]: Object
source: Observable
operator: FilterOperator {thisArg: undefined, predicate: ƒ}
source: Observable {_isScalar: false, source: Observable, operator: MergeMapOperator}
_isScalar: false
[[Prototype]]: Object
_isScalar: false
[[Prototype]]: Object

PLEASE HELP


Solution

  • This combination of Access-Control headers is invalid.

            resp.getHeaders().add("Content-Type", "application/json");
            resp.getHeaders().add("Access-Control-Allow-Origin", "*");
            resp.getHeaders().add("Access-Control-Allow-Headers", "*");
            resp.getHeaders().add("Access-Control-Allow-Credentials", "true");
    

    You cannot set Access-Control-Allow-Origin to * and also allow Access-Control-Allow-Credentials.

    For requests without credentials, the literal value "*" can be specified as a wildcard; the value tells browsers to allow requesting code from any origin to access the resource. Attempting to use the wildcard with credentials results in an error.

    This might be a large scale issue of the system architecture. For now you could test setting the Allow-Origin header like this:

            resp.getHeaders().add("Access-Control-Allow-Origin", "http://localhost:8100");
    

    However if it's supposed to work from an arbitrary number of clients another architecture might be necessary.

    CORS is a security feature. Do not "trial and error" around with security features!