Заголовок авторизации в ссылке img src

У меня есть api, который использует jwt для аутентификации. Я использую этот api для приложения vuejs. Я пытаюсь показать изображение в приложении, используя

<img src="my/api/link" />

Но api ожидает Authorization заголовок jwt token в нем.

Можно ли добавить заголовки в запрос браузера, подобные этому (ответ на несколько вопросов здесь заставил меня поверить, что это невозможно)?

Есть ли способ обойти это (используя js) или изменить сам api?

Ответ 1

Вы не можете выполнять проверку подлинности на изображениях, которые непосредственно используются как href в теге img. Если вы действительно хотите использовать этот тип аутентификации на своих изображениях, то лучше извлечь их с помощью ajax и затем вставить в свой html.

Ответ 2

<img src="/api/images/yourimage.jpg?token=here-your-token">

В бэкэнд вы проверяете JWT из queryparam.

Ответ 3

По умолчанию браузеры отправляют куки. Вы можете запретить отправку fetch cookie при fetch если вы установили header {credentials: 'omit'}. MDN

Пример полной fetch:

const user = JSON.parse(localStorage.getItem('user'));
let headers = {};

if (user && user.token) {
  headers = { 'Authorization': 'Bearer ' + user.token };
} 

const requestOptions = {
    method: 'GET',
    headers: headers,
    credentials: 'omit'
};

let req = await fetch('${serverUrl}/api/v2/foo', requestOptions);
if (req.ok === true) {
...

Теперь, когда вы входите в систему, на вашем веб-сайте веб-приложение может сохранять учетные данные как в localStorage, так и в cookie. Пример:

let reqJson = await req.json();
// response is: {token: 'string'}
//// login successful if there a jwt token in the response
if (reqJson.token) {
    // store user details and jwt token in local storage to keep user logged in between page refreshes
    localStorage.setItem('user', JSON.stringify({token: reqJson.token}));
    document.cookie = 'token=${reqJson.token};'; //set the cookies for img, etc
}

Таким образом, ваше веб-приложение использует localStorage, как и ваше приложение для смартфона. Браузер получает все статическое содержимое (img, video, href), отправляя куки по умолчанию.

На стороне сервера вы можете скопировать cookie файл в заголовок авторизации, если он отсутствует.

Node.js + экспресс-пример:

.use(function(req, res, next) { //function setHeader
  if(req.cookies && req.headers &&
     !Object.prototype.hasOwnProperty.call(req.headers, 'authorization') &&
     Object.prototype.hasOwnProperty.call(req.cookies, 'token') &&
     req.cookies.token.length > 0
   ) {
    //req.cookies has no hasOwnProperty function,
    // likely created with Object.create(null)
    req.headers.authorization = 'Bearer ' + req.cookies.token.slice(0, req.cookies.token.length);
  }
  next();
})

Надеюсь, это кому-нибудь поможет.

Ответ 4

вам нужно использовать staci патч для вашего img

<img src="my/api/icon/my-icon.png" />

или вам нужно получить путь на вашем сервере и использовать <img src= ${pathInServer} />. Все зависит от настроек вашего сервера.