Как загружать изображения, если я использую аутентификацию на основе токенов

У меня есть клиентское приложение в домене 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


  1. Первый метод просто создает маршрут без аутентификации (анонимный доступ) с параметром хеша подписи, который указывает, может ли ресурс быть загружен или нет.
<img src="http://server-domain.com/path/to/image?guid=f6fc84c9f21c24907d6bee6eec38cabab5fa9a7be8c4a7827fe9e56f2">

Когда сервер получает запрос, вы должны проверить guid, если время истечения не было достигнуто, и, конечно, проверить, является ли guid действительной подписью.

Этот подход используется несколькими серверами файлов/документов, такими как Dropbox, S3, поставщики CDN и т.д.

Смотрите технику в некоторых компаниях.


  1. Второму методу передается токен с помощью строки запроса с URL-адресом изображения.

    • Этот метод не рекомендуется, поскольку четко отображает URL-адрес, и многие серверы иногда пишут и предоставляют открытые журналы URL-адреса, к которому осуществляется доступ. Плохое замечание в том, что JWT, как правило, экспонируется, и пользователь может получить доступ ко многим функциям для дальнейшей загрузки изображения.
<img src="http://server-domain.com/path/to/image?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c">

Когда сервер получает запрос, вы должны проверить токен с помощью строки запроса и ответа с содержимым.


  1. Третий метод создает аутентифицированный 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.