Не удалось получить параметр заголовка в ContainerRequestFilter - PullRequest
2 голосов
/ 20 апреля 2019

Я создаю веб-сервисы на Java с Jersey2.0. Все работает, как ожидалось, когда я выполняю запрос от POSTMAN , но когда я выполняю запрос от клиентского приложения, я не могу получить параметр заголовка. Мое клиентское приложение на JavaScript. Кроме того, я добавил, что CORS разрешает параметры запроса источника в ContainerResponseContext .

Ниже показан мой ContainerResponseFilter класс, в который я добавляю CORS.

@Provider
class CORSFilter : ContainerResponseFilter {

    override fun filter(requestContext: ContainerRequestContext?, responseContext: ContainerResponseContext?) {
        responseContext?.apply {
            headers.add("Access-Control-Allow-Origin", "*")
            headers.add("Access-Control-Allow-Headers", "origin, content-type, authorization, accept, privatekey")
            headers.add("Access-Control-Allow-Credentials", "true")
            headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD")
        }
    }
}

Закрытый ключ - это имя моего заголовка для запроса. Теперь вот мой код для ContainerRequestFilter .

@Priority(AUTHENTICATION)
@Provider
class JsTokenFilterNeeded : JsBaseFilter(this::class.java.simpleName) {

    override fun filter(request: ContainerRequestContext?) {
        val path = request?.uriInfo?.path       
        val privateKeyHeaderValue = request?.getHeaderString("privatekey")
        println("private key -> $privateKeyHeaderValue")
    }
}

Я всегда получаю нулевое значение в privateKeyHeaderValue . Оба контейнера успешно зарегистрированы в ResourceConfig class.

На данный момент, я получаю, что заголовок «Access-Control-Allow-Origin» отсутствует на запрошенном ресурсе, вот журнал.

{host=[203.***.51.***:5555], connection=[keep-alive], access-control-request-method=[GET], origin=[http://localhost:38596], user-agent=[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36], access-control-request-headers=[privatekey], accept=[*/*], alexatoolbar-alx_ns_ph=[AlexaToolbar/alx-4.0.3], referer=[http://localhost:38596/], accept-encoding=[gzip, deflate], accept-language=[en-US,en;q=0.9]}

Редактировать 1 Вот мой код Js для клиентского приложения.

$.ajax(
    {
        type: "GET",
        headers: {
            'privatekey': privateKey
        },
        url: "http://***.124.**.76:5555/dcu/energy/"+active_import,
        data: {
            'dcu_id': '99220445',
            'tariff': 0
        },
        error: function (result) {
            console.log(result);
        },
        success: function (result) {
            console.log(result);
        }
    });

Edit2 Я использую ResourceConfig для регистрации моих провайдеров. Вот мой класс ResourceConfig.

class MyResourceConfig : ResourceConfig() {

    init {
        register(CORSFilter())
        register(JsTokenFilterNeeded())
    }
}

1 Ответ

2 голосов
/ 21 апреля 2019

Есть запрос предполетной проверки , который произошел до реального запроса. Предварительный запрос не отправляет заголовки (включая заголовок ключа). Это только отправляет заголовки, спрашивающие сервер, разрешен ли запрос. Поэтому, когда запрос предварительной проверки достигает фильтра, токена там не будет.

Что вам нужно сделать, так это заставить CorsFilter реализовать ContainerRequestFilter и a ContainerResponseFilter. Сделать это @PreMatching фильтр. Таким образом, он будет вызван перед фильтром токена. В фильтре request проверьте, не является ли это предполётным запросом. Если это так, то отмените запрос. Это приведет к тому, что запрос пропустит остальные фильтры запроса и сразу перейдет к фильтрам response . На стороне фильтра ответов вы можете добавить заголовки CORS.

Вы должны прочитать ОБНОВЛЕНИЕ в этом посте, чтобы лучше понять поток протокола CORS, а также увидеть лучшую реализацию CorsFilter, которую вы можете использовать, которая должна работать в вашем сценарии.

...