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?
Solution 1:
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.
Solution 2:
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.
Solution 3:
<img src="/api/images/yourimage.jpg?token=here-your-token">
In the backend you validate JWT from queryparam.