Подписанные ссылки
Почти все REST сервисы имеют аутентификацию. Есть несколько способов её сделать:
- basic. В каждый запрос добавляется заголовок “Authorization” с логином и паролем.
GET / HTTP/1.1
Host: example.org
Authorization: Basic Zm9vOmJhcg==
- token. REST сервис обменивает логин и пароль на специальный токен аутентификации. Клиент должен все последующие запросы делать с этим токеном.
GET / HTTP/1.1
Host: example.org
Authorization: Bearer 9yro9yueihfw497y33497y3oeiruhfvskdgjhfaowidayuh
Аутентификация на основе токенов наиболее безопасная и гибкая. Токены можно отзывать и обновлять, в них можно класть дополнительную информацию. С ними очень удобно работать из SPA приложений. Например, доступ к защищённому ресурсу можно сделать следующим образом:
- Установить единый токен для всех запросов
axios.defaults.headers.common['Authorization'] = 'Bearer ' + token
- Делать вызовы к защищённым методам
$http.get('/admin/config/general').then(function (response) {
console.log(response)
})
Но что делать, если необходимо защитить статические ресурсы? Например, в r2cloud статические ресурсы это снимки со спутников, телеметрия и метрики производительности. Есть несколько способов.
Data-src атрибут
Схема работы следующая:
- Вместо обычного
src
атрибута, указываетсяdata-src
<img data-src="/admin/observation/picture.png">
- После загрузки страницы код на javascript должен проходить по всем элементам img, загружать через ajax картинки и проставлять их в тэг
src
$("img").attr("src", "data:image/png;base64," + response);
У этого метода есть один большой недостаток: необходимо на каждой странице выполнять javascript код, который будет подгружать картинки. Но есть и другой способ.
Подписанные ссылки
Суть метода заключается в том, что к ссылке добавляется подпись. Эта подпись обладает следующими свойствами:
- позволяет получить данные без использования заголовка
Authorization
. - короткоживущая. Подпись содержит в себе время создания ссылки. Это время проверяется на сервере, и если оно превышает время жизни ссылки, то её данные нельзя получить.
- её нельзя подделать. Она сгенерирована с использованием секретного ключа, который известен только на сервере.
Вот как выглядит использование таких ссылок на странице:
<img src="/img/a.jpg?hash=3679d97d8b1d497743cd8da8ba0440f5×tamp=1508716800000">
Где hash
- это подпись, timestamp
- время генерации ссылки. На сервере подпись можно генерировать следующим образом:
computeMD5(path + timestamp + password)
Здесь нужно обратить внимание на то, что время включено в алгоритм генерации подписи. Это позволит защититься от атак повторного воспроизведения.
Кэширование
Данные, полученные по подписанным ссылкам, могут быть кэшированы браузером. Из-за этого необходимо аккуратно выставить заголовки ответа: не кэшировать на прокси серверах и кэшировать в браузере только на время жизни ссылки:
Cache-Control: private, max-age=600
Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT