为什么浏览器在经过身份验证的 XMLHttpRequest 后不重用授权标头? [英] Why doesn't the browser reuse the authorization headers after an authenticated XMLHttpRequest?

查看:23
本文介绍了为什么浏览器在经过身份验证的 XMLHttpRequest 后不重用授权标头?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Angular 开发单页应用程序.后端公开需要基本身份验证的 REST 服务.获取 index.html 或任何脚本不需要身份验证.

I'm developing Single Page App using Angular. The backend exposes REST services that require Basic authentication. Getting index.html or any of the scripts does not require authentication.

我有一个奇怪的情况,我的一个视图有一个 <img>,其中 src 是需要身份验证的 REST API 的 url. 由浏览器处理,我没有机会为它发出的 GET 请求设置授权标头.这会导致浏览器提示输入凭据.

I have an odd situation where one of my view has a <img> where the src is the url of a REST API that requires authentication. The <img> is processed by the browser and I have no chance to set the authorization header for GET request it makes. That causes the browser to prompt for credentials.

我试图通过这样做来解决这个问题:

I attempted to fix this by doing this:

  1. 在源代码中将 img src 留空
  2. 在文档准备好"时,使用 Authorization 标头向服务 (/api/login) 发出 XMLHttpRequest,以便进行身份验证.立>
  3. 完成该调用后,设置 img src 属性,认为届时浏览器将知道在后续请求中包含 Authorization 标头...
  1. Leave img src empty in the source
  2. At "document ready", make an XMLHttpRequest to a service (/api/login) with the Authorization header, just to cause the authentication to occur.
  3. Upon completing that call, set the img src attribute, thinking that by then, the browser would know to include the Authorization header in subsequent requests...

...但事实并非如此.对图像的请求在没有标题的情况下发出.如果我输入凭据,则页面上的所有其他图像都是正确的.(我也试过和 Angular 的 ng-src 但产生了相同的结果)

...but it doesn't. The request for the image goes out without the headers. If I enter the credentials, then all other images on the page are right. (I've also tried and Angular's ng-src but that produced the same result)

我有两个问题:

  1. 为什么在 XMLHttpRequest 成功后,浏览器 (IE10) 没有在所有请求中包含标头?
  2. 我可以做些什么来解决这个问题?
  1. Why didn't the browser (IE10) include the headers in all requests after a successful XMLHttpRequest?
  2. What can I do to work around this problem?

<小时>

@bergi 询问请求的详细信息.在这里.

请求/api/login

Request to /api/login

GET https://myserver/dev30281_WebServices/api/login HTTP/1.1
Accept: */*
Authorization: Basic <header here>
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; WOW64; Trident/6.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729)
Connection: Keep-Alive

响应(/api/login)

Response (/api/login)

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 4
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 20 Dec 2013 14:44:52 GMT

请求/user/picture/2218:

Request to /user/picture/2218:

GET https://myserver/dev30281_WebServices/api/user/picture/2218 HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; WOW64; Trident/6.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729)
Connection: Keep-Alive

然后 Web 浏览器会提示输入凭据.如果我输入它们,我会收到以下回复:

And then the web browser prompts for credentials. If I enter them, I get this response:

HTTP/1.1 200 OK
Cache-Control: public, max-age=60
Content-Length: 3119
Content-Type: image/png
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 20 Dec 2013 14:50:17 GMT

推荐答案

基本思路

通过 JavaScript 加载图像并将其显示在网站上.优点是身份验证凭据永远不会进入 HTML.他们会在 JavaScript 方面抵制.

Basic idea

Load the images via JavaScript and display them on the site. The advantage is that the authentication credentials will never find their way into the HTML. They will resist at the JavaScript side.

这是基本的 AJAX 功能(另见 <代码>XMLHttpRequest::open(method, uri, async, user, pw)):

That's basic AJAX functionality (see also XMLHttpRequest::open(method, uri, async, user, pw)):

var xhr = new XMLHttpRequest();
xhr.open("GET", "your-server-path-to-image", true, "username", "password");

xhr.onload = function(evt) {
  if (this.status == 200) {
    // ...
  }
};

第 2 步:格式化数据

现在,我们如何显示图像数据?使用 HTML 时,通常会为图像元素的 src 属性分配一个 URI.除了我们使用 data URIs 之外,我们可以在这里应用相同的原则'正常' http(s):// 派生.

Step 2: format the data

Now, how can we display the image data? When using HTML, one would normally assign an URI to the src attribute of the image element. We can apply the same principle here except for the fact that we use data URIs instead of 'normal' http(s):// derivates.

xhr.onload = function(evt) {
  if (this.status == 200) {
    var b64 = utf8_to_b64(this.responseText);
    var dataUri = 'data:image/png;base64,' + b64; // Assuming a PNG image

    myImgElement.src = dataUri;
  }
};

// From MDN:
// https://developer.mozilla.org/en-US/docs/Web/API/window.btoa
function utf8_to_b64( str ) {
    return window.btoa(unescape(encodeURIComponent( str )));
}

画布

还有另一个选项是在 字段中绘制加载的数据.这样,用户将无法右键单击图像(画布所在的区域),而不是 和数据 URI,用户将在其中看到很长的图像查看图像属性面板时的数据 URI.

Canvas

There is also another option which consists in painting the loaded data in a <canvas> field. This way, the user won't be able to right-click the image (the area where the canvas is positioned) as opposed to the <img> and data URIs where the user will see a long data URI when viewing the image properties panel.

这篇关于为什么浏览器在经过身份验证的 XMLHttpRequest 后不重用授权标头?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆