Отфильтровать ответ и сохранить что-то в memcached с помощью nginx+Lua

У меня есть серверная часть, которая генерирует три токена JWT: токен ссылки, токен доступа и токен обновления. Токен ссылки хранит ссылку на токен доступа, который используется для доступа к API, а токен обновления используется для повторного выпуска токена доступа по истечении времени ожидания. Проблема в том, что я не хочу передавать токен доступа клиенту, а хочу использовать nginx для его хранения в memcached. Итак, вся моя задача состоит в том, чтобы отфильтровать ответ от бэкэнда, который на данный момент выглядит так же просто, как:

{"reference_token":"...","access_token":"...","refresh_token":"..."}

Nginx должен отфильтровать этот ответ, получить токен доступа из этого ответа и сохранить его в memcached. Наконец, он должен вернуть клиенту новый ответ:

{"reference_token":"...","refresh_token":"..."}

Как видите, access_token больше не должно быть. Токен доступа — это то, что я стараюсь обезопасить, а не показывать и даже передавать клиенту. Чего я не знаю, так это того, как лучше всего это реализовать, какой блок Lua я должен использовать для этой задачи. Я знаю о body_filter_by_lua , но в документации кратко говорится, что:

Обратите внимание, что следующие функции API в настоящее время отключены в этом контексте из-за ограничений в текущей реализации выходного фильтра NGINX.

Итак, похоже, что фильтрация тела довольно ограничена, и я даже не уверен, можно ли вызвать memcached API внутри этого блока. Итак, как я могу реализовать свою задачу в реальном мире? По крайней мере, какие приемы Lua (openresty) я должен использовать для решения этой задачи?


person Jacobian    schedule 14.07.2017    source источник


Ответы (1)


Вы можете отправить подзапрос (например, ngx.location.capture) к вашему бэкэнду, например, в вашем обработчике контента. Затем вы можете отфильтровать тело по своему усмотрению, а затем использовать lua-resty-memcached, который использует API-интерфейс cosocket.

Недостатком этого подхода является то, что у вас будет полностью буферизованный прокси.

person Alexander Altshuler    schedule 17.07.2017
comment
Спасибо, Александр! Не могли бы вы немного пояснить, почему полная буферизация прокси-сервера является недостатком? Я новичок в nginx и не знаю этих нюансов. - person Jacobian; 17.07.2017
comment
Представьте, что вышестоящий сервер отвечает огромным телом. Обычно это будет отправлено в каком-то куске. Nginx обрабатывает каждый фрагмент и по умолчанию отправляет его обратно клиенту, не дожидаясь полного тела ответа. Это экономит некоторые ресурсы и более производительно. При полном буферизованном подходе вам нужно будет где-то сохранить заголовки/тело. Если вы сохраните его в памяти, у вас может быть подкачка при высокой нагрузке. Если вы сохраните его в файле, у вас будут накладные расходы на ввод-вывод. - person Alexander Altshuler; 17.07.2017