Реакция (CORS с Keycloak): заголовок не установлен или заголовок не установлен дважды, вызов OPTIONS, но статус HTTP (отменен) - PullRequest
1 голос
/ 05 марта 2019

Я работаю над интерфейсом реакции, использующим REST для связи с бэкэндом JAVA (микросервис Thorntail), защищенным Keycloak.С использованием GET и POST проблем нет, но попытка DELETE возвращает разные ошибки в зависимости от моих настроек.Мой файл CorsFilter.java по умолчанию не имеет настроек:

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;

@Provider
public class CorsFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext,
                       ContainerResponseContext responseContext) { 
    }
}

Функция REST My React:

static deleteCourier = function (origin, courierNumber, endpoint, data, requestListener) {
    keycloak.updateToken(5).then(function () {
        const request = new XMLHttpRequest();
        request.open("DELETE", HTTP_SCHEME + "://" + backendUrl + endpoint + "/" + origin + "/" + courierNumber);
        request.setRequestHeader('Authorization', 'Bearer' + keycloak.token);
        request.send();
    }).catch(function () {
        console.log('Failed to refresh the token, or the session has expired');
        keycloak.init({onLoad: 'login-required'}).success(function (authenticated) {
            if (authenticated) {
                Rest.deleteCourier(origin, courierNumber, endpoint, data, requestListener);
            } else {
                console.log('kc not authenticated');
            }
        }).error(function () {
            console.log('kc init failed');
        });
    }).then(function () {
        Rest.updateData(data, requestListener, endpoint)
    });
};

Вызов API REST бэкэнда:

import javax.ejb.EJB;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.OPTIONS;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("/device")
public class DeviceEndpoint {   

    @DELETE
    @Path("/{origin}/{courierNumber}")
    public Response delete(
            @PathParam("origin") String origin,
            @PathParam("courierNumber") String courierNumber) {
        try {
            deviceBF.removeCourier(origin, courierNumber);
        } catch (PhoenixClientException e) {
            return Response.ok(new WebApplicationException(e)).build();
        }
        return Response.ok().build();
    }
}

В Keycloak «Web Origins» установлен на «*».

Используя эту настройку, GET и POST работают как задумано.При попытке удалить устройство на вкладке сети в моем браузере отображается состояние «(отменено)» и (скопировано как извлечение из Googles Chrome):

извлечение («http://192.168.0.66:8282/auth/realms/customer/protocol/openid-connect/auth?response_type=code&client_id=mystique&redirect_uri=http%3A%2F%2F192.168.0.66%3A8080%2Fmystique%2Frest%2Fdevice%2Fdts%2Fd&state=22a1dba6-e12e-4852-8cba-0f86a4799d4f&login=true&scope=openid",){"credentials": "omit", "referrer": "http://localhost:3000/","referrerPolicy":"no-referrer-when-downgrade","body":null,"method":"DELETE","mode":"cors"});

И вывод консоли:

Доступ к XMLHttpRequest в 'http://192.168.0.66:8080/mystique/rest/device/dts/d' from origin 'http://localhost:3000' заблокировано политикой CORS: в запрошенном ресурсе отсутствует заголовок' Access-Control-Allow-Origin '.

Отправка запросов GET и POSTЗапрос OPTIONS перед реальным запросом. В этом случае такой запрос OPTIONS не отправляется.

Когда я помещаю вывод консоли в мой REST API, я вижу, что он не вызывается. Но путь должен быть в порядке. ПротестированоAPI REST через Postman и все работает.

Если я изменю файл CorsFilter.java и добавлю, например:

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

..., консоль браузера покажет мне:

Доступ к XMLHttpRequest в 'http://192.168.0.66:8080/mystique/rest/websocket-auth/token' от источника' http://localhost:3000' заблокирован CORПолитика S: Заголовок 'Access-Control-Allow-Origin' содержит несколько значений 'http://localhost:3000, http://localhost:3000',, но разрешено только одно.

Я искал свойкод, а также все мои файлы конфигурации для второй записи и ничего не нашел.Я понятия не имею, откуда он.

Добавление следующего в CorsFilter.java, кажется, не имеет никакого эффекта.

responseContext.getHeaders().add(
            "Access-Control-Allow-Methods",
            "GET, POST, PUT, DELETE, OPTIONS");

В дополнение к ранее описанному поведению устройство,курьер принадлежит, удаляется.Я не уверен, соответствует ли это проблеме с CORS или это единственная проблема.Изменение данных устройства без удаления курьера (что также делается через REST) ​​работает как задумано.Но при удалении курьера до обновления мое устройство удаляется.

Надеюсь, кто-нибудь сможет мне помочь с этим.

...