Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authorization header in img src link

I have an api that uses jwt for authencation. I am using this api for a vuejs app. I am trying to display an image in the app using

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

But the api expects Authorization header with jwt token in it.

Can I add headers to browser request like this(Answer to few questions here has made me believe it's not possible)?

Is there any way around it(using js) or should i change the api itself?

like image 840
Ragas Avatar asked Oct 09 '17 09:10

Ragas


People also ask

How do I change the Authorization header in URL?

It is indeed not possible to pass the username and password via query parameters in standard HTTP auth. Instead, you use a special URL format, like this: http://username:[email protected]/ -- this sends the credentials in the standard HTTP "Authorization" header.

How do I send the Authorization header in HTTP?

It is a simple authentication scheme built into the HTTP protocol. The client sends HTTP requests with the Authorization header that contains the word Basic, followed by a space and a base64-encoded(non-encrypted) string username: password. For example, to authorize as username / Pa$$w0rd the client would send.

How do I pass Authorization bearer in header?

To send a request with the Bearer Token authorization header, you need to make an HTTP request and provide your Bearer Token with the "Authorization: Bearer {token}" header. A Bearer Token is a cryptic string typically generated by the server in response to a login request.


3 Answers

You can not perform authentication on images which are directly used as href in img tag. If you really want this type of authentication on your images, then it's better to fetch them using ajax and then embed in your html.

like image 134
Tapas Avatar answered Oct 24 '22 05:10

Tapas


By default browsers are sending cookies. You can prevent cookie sending in fetch if you set header's {credentials: 'omit'}. MDN

Full fetch example:

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) {
...

Now, when you are login in, in your website, the webapp could save to credentials into both localStorage and cookie. Example:

let reqJson = await req.json();
// response is: {token: 'string'}
//// login successful if there's 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
}

So your webapp uses localStorage, just like your smartphone application. Browser gets all the static contents (img, video, a href) by sending cookies by default.

On the server side, you can copy the cookie to authorization header, if there is none.

Node.js+express example:

.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();
})

I hope it helps someone.

like image 39
arcol Avatar answered Oct 24 '22 06:10

arcol


You can use a Service Worker to intercept the img fetchs and add the Authorization header with the JWT token before hitting the server. Described in:

  • https://www.sjoerdlangkemper.nl/2021/01/06/adding-headers-to-image-request-using-service-workers/
  • https://www.twelve21.io/how-to-access-images-securely-with-oauth-2-0/#:~:text=4.%20USE%20SERVICE%20WORKERS
like image 8
Nahuel Greco Avatar answered Oct 24 '22 06:10

Nahuel Greco