Как загружать изображения, если я использую аутентификацию на основе токенов
У меня есть клиентское приложение в домене client-domain.com
и серверное приложение в домене server-domain.com
. На стороне сервера есть API. Клиентское приложение отправляет запросы AJAX серверному приложению. Я использую аутентификацию на основе токенов, поэтому приложение на стороне клиента отправляет токен в заголовках с каждым запросом AJAX, например: "Авторизация: Bearer {some token}". Он отлично работает с запросами AJAX, когда мне нужно получить или опубликовать некоторые данные.
Но серверный API также поддерживает файлы. Например, изображения. Файлы являются закрытыми, только пользователи, прошедшие аутентификацию, могут их получить. И мне нужно показать эти изображения на стороне клиента в теге <img>
. Я не могу заставить их использовать <img src="http://server-domain.com/path/to/image">
, потому что в этом случае браузер не будет отправлять заголовок авторизации на сервер.
Что такое принятое решение? Как клиентские приложения загружают изображения с сервера API?
Ответы
Ответ 1
Есть три метода, чтобы решить это, лучший способ решить это, используя подписанные URL
- Первый метод просто создает маршрут без аутентификации (анонимный доступ) с параметром хеша подписи, который указывает, может ли ресурс быть загружен или нет.
<img src="http://server-domain.com/path/to/image?guid=f6fc84c9f21c24907d6bee6eec38cabab5fa9a7be8c4a7827fe9e56f2">
Когда сервер получает запрос, вы должны проверить guid, если время истечения не было достигнуто, и, конечно, проверить, является ли guid действительной подписью.
Этот подход используется несколькими серверами файлов/документов, такими как Dropbox, S3, поставщики CDN и т.д.
Смотрите технику в некоторых компаниях.
-
Второму методу передается токен с помощью строки запроса с URL-адресом изображения.
- Этот метод не рекомендуется, поскольку четко отображает URL-адрес, и многие серверы иногда пишут и предоставляют открытые журналы URL-адреса, к которому осуществляется доступ. Плохое замечание в том, что JWT, как правило, экспонируется, и пользователь может получить доступ ко многим функциям для дальнейшей загрузки изображения.
<img src="http://server-domain.com/path/to/image?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c">
Когда сервер получает запрос, вы должны проверить токен с помощью строки запроса и ответа с содержимым.
-
Третий метод создает аутентифицированный cookie для проверки доступа к изображению.
- Этот метод не рекомендуется, поскольку не соответствует шаблону API (аутентификация на основе webapi/token в целом).
Когда сервер получает запрос, вам нужно проверить, является ли валидный cookie действительным.
Ответ 2
Мое решение в основном этой же проблемы, основанное на ответе Джефферсона Тенорио, приведенном ниже (вариант 1), заключалось в том, чтобы подписать URL-адрес моего вызова API с помощью шифрования изображения и токена пользователя JWT, например, path/to/image?token=xxxx
. В laravel это легко сделать с помощью encrypt($your_object)
и decrypt($token)
(https://laravel.com/docs/5.7/encryption), а затем я использовал извлеченный токен, чтобы убедиться, что у пользователя есть доступ к файлу. обсуждаемый. Но, вероятно, есть много других библиотек, способных справиться с этим.
Мне было бы любопытно, если есть какие-либо проблемы безопасности, но с моей точки зрения JWT никогда не раскрывается с помощью простого текста, и шифрование основывается на секретном ключе, к которому злоумышленники не должны иметь доступ, поэтому кажется, что он должен быть достаточно безопасным, Моя единственная реальная жалоба в том, что токен довольно долго использует этот метод, который не подходит для презентабельных URL.