React(带Keycloak的CORS):没有设置标头或设置标头两次,没有OPTIONS调用,但HTTP状态(已取消)

时间:2019-03-05 19:37:19

标签: java reactjs rest cors keycloak

我正在使用REST与由Keycloak保护的JAVA后端(Thorntail微服务)进行通信的前端工作。使用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) { 
    }
}

我的React REST功能:

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)
    });
};

调用后端的REST API:

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可按预期工作。尝试删除设备时,浏览器中的“网络”标签显示以下状态:“(已取消)”和“(从Google Chrome浏览器中复制)”:

  

fetch(“ 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“}});

控制台输出为:

  

CORS策略已阻止从来源“ http://192.168.0.66:8080/mystique/rest/device/dts/d”访问“ http://localhost:3000”处的XMLHttpRequest:请求的资源上没有“ Access-Control-Allow-Origin”标头。

GET和POST请求在实际请求之前发送OPTIONS请求。在这种情况下,不会发送任何此类OPTIONS请求。

当我将控制台输出放到我的REST API时,我可以看到它没有被调用。但是路径应该没问题。通过Postman测试了REST API,一切正常。

如果我修改CorsFilter.java文件并添加例如:

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

...浏览器控制台向我显示:

  

CORS策略已阻止从源“ http://192.168.0.66:8080/mystique/rest/websocket-auth/token”访问“ http://localhost:3000”处的XMLHttpRequest:“ 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完成)按预期工作。但是在更新之前删除快递将删除我的设备。

我希望任何人都可以帮助我。

0 个答案:

没有答案