Как использовать лак с RESTful API по протоколу Oauth2?

У меня есть RESTful Api, написанный на Symfony2 с использованием FosOauth2Serverbundle, FosRestBundle и FosUserBundle. Я планирую поставить лак перед своим API в качестве обратного прокси. Поскольку мое приложение, использующее мой API, всегда отправляет access_token в качестве параметра или кэширования заголовков почти каждый запрос как разные запросы, и это неэффективно. Поскольку я использую пользователя access_token в своем контроллере для безопасности, а иногда и для контента, я не могу полностью удалить access_token из запроса из запроса в vcl_recv. После нескольких поисков в Интернете я наткнулся на решение для аутентификации http://www.adayinthelifeof.nl/2012/07/06/using-varnish-to-offload-and-cache-your-oauth-запросы/ . Однако я не могу понять, как указать текущему пользователю FosUserBundle в заголовке передать безопасность в security.yml:

  access_control:
   - { path: ^/2013-08-30/foo$, role: ROLE_USER, requires_channel: https, methods: [GET] }

Короче говоря, как я могу сообщить FosUserBundle о текущем пользователе в заголовке запроса (отправить из лака)?


person Omer Temel    schedule 30.12.2013    source источник


Ответы (1)


Есть несколько способов обойти подобные проблемы, если вы хотите, чтобы два немного разных запроса возвращали один и тот же ответ (т.е. запросы отличаются только параметром GET ключа API), самое быстрое и простое решение — настроить определение уникальности лака с помощью функция hash_data в vcl_hash. Вы просто удаляете все элементы URL, которые не способствуют тому, чтобы ответ был четким, и хешируете его. Например, если URL-адрес содержит «access_token», удалите все параметры GET из хеш-ключа:

sub vcl_hash {
  if (req.url ~ "access_token"){
    set req.url = regsub(req.url, "^https?://(.*)\?access_token=.*$","\1");
  }
  hash_data(req.url);
}

Другими словами, это будет кэшировать mydomain.com/some/restful/request?access_token=abc и mydomain.com/some/restful/request?access_token=def как соответствующие.

Если ответ в основном одинаков с небольшими областями, которые должны быть уникальными (например, одно значение в большом ответе JSON или элемент div в заголовке с надписью «Добро пожаловать, имя пользователя!»), вы можете использовать краевая сторона включает. Загвоздка, конечно, в том, что это требует настройки того, что возвращает серверная часть.

person jaybrau    schedule 27.06.2014
comment
Разве это не сбрасывает проверку подлинности? Таким образом, даже если я передам неверный access_token Varnish, он вернет кешированные данные, которые обычно требуют аутентификации, если они доставляются бэкэндом? - person HenningCash; 06.05.2015
comment
Нет, это не влияет на запрос к серверной части, это просто позволяет кэшировать результаты, не требуя access_token. Конечно, если в результатах есть какие-либо конфиденциальные данные пользователя, этот метод является дырой в безопасности, поэтому вам нужно иметь отдельную логику для URL-адресов, которые возвращают конфиденциальные данные. Идея здесь состоит в том, чтобы позволить аутентифицированным пользователям пользоваться преимуществами кеша для страниц, которые в любом случае общедоступны. Для страниц, которые не являются общедоступными, их по-прежнему можно кэшировать с помощью маркера доступа, но тогда каждый пользователь фактически имеет личный кеш. - person jaybrau; 15.10.2015
comment
Что делать, если я не добавляю токен в URL, но у меня есть запрос токена JWT в заголовках? У меня есть сложный вопрос здесь - person LCJ; 23.08.2016
comment
Вы также можете хэшировать заголовки. Например, для заголовка User-Agent вы получаете доступ к нему как req.http.User-Agent. Вы можете вызывать hash_data несколько раз, поэтому вы можете просто добавить что-то вроде if (req.http.User-Agent){ hash_data(req.http.User-Agent);} - person jaybrau; 23.08.2016