img src链接中的授权标头

Rag*_*gas 30 html javascript jwt

我有一个api使用jwt的authencation.我正在使用这个api的vuejs应用程序.我正在尝试使用应用程序在应用程序中显示图像

<img src="my/api/link" />
Run Code Online (Sandbox Code Playgroud)

但是api期望Authorization标题jwt token在里面.

我可以像这样在浏览器请求中添加标题(这里几个问题的回答让我相信它不可能)?

有没有办法(使用js)或我应该改变api自己?

小智 13

您无法对img标记中直接用作href的图像执行身份验证.如果你真的想在你的图像上使用这种类型的身份验证,那么最好使用ajax获取它们然后嵌入你的html中.

  • 要添加这个答案:您甚至无法在服务工作线程“fetch”处理程序中手动/强制添加标头。在发出实际的网络请求之前它将被删除。 (4认同)
  • 一个链接就好了 (3认同)

Ale*_*xys 10

<img src="/api/images/yourimage.jpg?token=here-your-token">
Run Code Online (Sandbox Code Playgroud)

在后端,您从 queryparam 验证 JWT。

  • 我不建议这样做,令牌就像密码,如果您的用户复制它然后将其提供给其他人,则他们可以看到图像。如果用户是恶意的,他们就可以使用该令牌从原始用户那里获取更多信息。 (25认同)
  • JWT 位于 cookie 或本地存储中。如果用户是恶意的,则可以随时使用该令牌。那么 JWT 不是问题。 (9认同)
  • @ShafiqueJamal 即使您在 HTTP 标头中包含 JWT,它仍然以明文形式发送。从浏览器使用访问令牌等时始终需要 HTTPS (8认同)
  • 但是你的令牌是以纯文本形式发送的,不是吗? (6认同)
  • 可能的风险:用户右键单击图像并在公共计算机上的另一个选项卡中打开它。他离开了电脑。攻击者进入 te 计算机并开始输入由浏览器自动完成的基本 url(这不是秘密),其中包含 jwt 的参数。 (5认同)
  • 正如 @Exocomp 所说这是不安全的,开发人员如果缩小令牌范围就可以提高安全性。 (2认同)

arc*_*col 10

默认情况下,浏览器会发送 cookie。您可以防止饼干在发送fetch,如果你设置页眉的{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) {
...
Run Code Online (Sandbox Code Playgroud)

现在,当你正在登录,在您的网站,web应用程序可以保存到凭据为双方的localStorage和饼干。例子:

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
}
Run Code Online (Sandbox Code Playgroud)

所以你的 webapp 使用 localStorage,就像你的智能手机应用程序一样。默认情况下,浏览器通过发送 cookie 来获取所有静态内容(img、video、a href)。

在服务器端,您可以将 cookie 复制到授权标头(如果没有)。

Node.js+express 示例:

.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();
})
Run Code Online (Sandbox Code Playgroud)

我希望它可以帮助某人。

  • 这是一个聪明的解决方案:在客户端将 jwt 映射到适当的 Web 标准(cookie),并在后端取消映射它们! (2认同)

Lui*_* F. 9

这是我基于 Tapas 的回答和这个问题How to display Base64 images in HTML?的解决方案。

let jwtHeader = {headers: { Authorization: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpX..."}
let r = await axios.get(`/path/image`, {...jwtHeader, responseType:"arraybuffer"});
let d = Buffer.from(r.data).toString('base64');
let a = document.createElement('img');

a.src = `data:image/png;base64, ${d}`;
a.width = 300;
a.height = 300;
document.getElementById("divImage").appendChild(a);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,html 将有一个 <div id="divImage">


Dot*_*ert 6

我经常使用的解决方法是利用所谓的 nonce API 端点。当从经过身份验证的客户端调用此端点时,会生成并返回一个简短的字符串(可以是 guid)(例如 30 秒)。在服务器端,如果您愿意,您当然可以将当前用户数据添加到随机数中。

然后将随机数添加到图像的查询字符串中并在服务器端进行验证。此解决方法的成本是额外的 API 调用。但是,此解决方法的主要目的是提高安全保证。奇迹般有效 ;) 。