#scala #cookies #header #composition #lagom
Вопрос:
я хочу написать код, который обновит файл cookie (через http-заголовок set-cookie) в Lagom.
Для уточнения файл cookie представляет собой закодированную строку (например, AES).
Давайте возьмем состав вызова службы lagom для аутентификации из служб реализации и отредактируем его
def authenticated[Request, Response](
serviceCall: User => ServerServiceCall[Request, Response]
) = ServerServiceCall.composeAsync { requestHeader =>
//Get cookie from header and decode it
val cookie = decodeCookie(requestHeader)
//Get user based on cookie decode function
val userLookup = getUser(cookie)
userLookup.map {
case Some(user) =>
serviceCall(user)
case None => throw Forbidden("User must be authenticated")
}
}
Можно ли манипулировать заголовками ответов serviceCall(пользователя)?
Я попробовал что-то вроде этого:
serviceCall( employee ).handleResponseHeader { case (responseHeader, response) =>
responseHeader.withHeader("Set-Cookie",encodeCookie("NewCookieStringExample")) // Add header
response
}
Но функция handleResponseHeader требует только ответа[T], так как результат и заголовок не будут изменены, потому что неизменяемы.
Я знаю, что могу передать файл cookie serviceCall(пользователю) и в каждой реализации вызова службы возвращать кортеж с заголовком ответа и ответом, но это повлияет на все конечные точки и добавит гораздо больше кода.
Использование HeaderFilter также возможно, но это позволило бы декодировать и кодировать cookie дважды в одном запросе (в фильтре заголовка и в составе проверенного вызова службы )
Какие-нибудь советы?
Ответ №1:
Вы можете вернуть измененный заголовок и ответ в виде кортежа:
serviceCall( employee ).handleResponseHeader((responseHeader, response) => {
val modifiedHeader = responseHeader.withHeader("Set-Cookie",encodeCookie("NewCookieStringExample")) // Add header
(modifiedHeader, response)
})
Кстати, приведенный пример не компилируется для меня. composeAsync
хочет Future[ServerServiceCall[...]]
.
Комментарии:
1. Хорошая идея. Сочинять асинхронно-это моя ошибка из-за копирования вставки (мой код будет использоваться в будущем). Я попробовал это сначала,но аутентифицированная функция жаловалась на неправильный тип (требуется ответ, но (ResponseHeader, ответ)). Я думал, что это ошибка в этой функции, но это была ошибка в функции выше (для аутентификации требуется ответ для возврата). Спасибо за помощь.