为什么不浏览器重复使用验证XMLHtt prequest后授权头? [英] Why doesn't the browser reuse the authorization headers after an authenticated XMLHttpRequest?

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

问题描述

我使用的角度开发单页的应用程序。后端暴露了需要基本身份认证REST服务。获取index.html或任何脚本不需要身份验证。

我有一个奇怪的情况:我的观点的人有一个< IMG> 其中的src 是一个REST API需要身份验证的URL。在< IMG> 是由浏览器处理,我没有机会来设置它使GET请求授权头。这会导致浏览器提示输入凭据。

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


  1. IMG 的src 空源

  2. 在文件准备,使一个 XMLHtt prequest 来服务( / API /登录 )与授权头,只是导致出现的身份认证。

  3. 在完成这一号召,将 IMG SRC 属性,以为届时,浏览器会知道,包括在后续请求的授权头...

...但事实并非如此。该图像的要求熄灭无头。如果我输入凭据,那么页面上的所有其它图像是正确的。
(我也试过和角度的 NG-SRC 但产生同样结果)

我有两个问题:


  1. 为什么没有浏览器(IE10)包括所有请求头后,一个成功的 XMLHtt prequest

  2. 我能做些什么来解决这个问题?


@bergi要求的请求的详细信息。在这里,他们是。

请求/ API /登录

  GET https://开头MYSERVER / dev30281_WebServices / API /登录HTTP / 1.1
接受:* / *
授权:基本<这里头>
接受编码:gzip,紧缩
用户代理:Mozilla的/ 4.0(兼容; MSIE 7.0; Windows NT的6.2; WOW64;三叉戟/ 6.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729)
连接:保持活动

响应(/ API /登录)

  HTTP / 1.1 200 OK
缓存控制:无缓存
编译:无缓存
内容长度:4
内容类型:应用程序/ JSON的;字符集= UTF-8
过期:-1
服务器:Microsoft-IIS / 8.0
的X ASPNET-版本:4.0.30319
的X已启动方式:ASP.NET
日期:星期五,2013年12月20日14时44分五十二秒GMT

请求/用户/图片/ 2218:

  GET https://开头MYSERVER / dev30281_WebServices / API /用户/图片/ 2218 HTTP / 1.1
接受:* / *
接受编码:gzip,紧缩
用户代理:Mozilla的/ 4.0(兼容; MSIE 7.0; Windows NT的6.2; WOW64;三叉戟/ 6.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729)
连接:保持活动

然后是Web浏览器提示输入凭据。如果我进入其中,我得到这样的答复:

  HTTP / 1.1 200 OK
缓存控制:公众,最大年龄= 60
内容长度:3119
内容类型:图像/ PNG
服务器:Microsoft-IIS / 8.0
的X ASPNET-版本:4.0.30319
的X已启动方式:ASP.NET
日期:星期五,2013年12月20日14时50分17秒GMT


解决方案

基本思路

通过JavaScript加载图像并在网站上显示。其优点是,身份验证凭据永远不会找到自己的方式到HTML。他们将抵制在JavaScript端。

步骤1:通过JS加载图像数据

这是基本的AJAX功能(也<一见href=\"https://developer.mozilla.org/en-US/docs/Web/API/XMLHtt$p$pquest#open%28%29\"><$c$c>XMLHtt$p$pquest::open(method, URI,异步用户,PW) ):

  VAR XHR =新XMLHtt prequest();
xhr.open(GET,您的服务器路径到图像,真正的用户名,密码);xhr.onload =功能(EVT){
  如果(this.status == 200){
    // ...
  }
};

步骤2:格式化数据

现在,我们怎样才能显示图像数据?当使用HTML,人们通常会分配一个URI的图像元素的的src 属性。在这里我们可以采用同样的原则,除了这一事实,我们使用数据URI的而不是正常 HTTP(S):// 衍生物

  xhr.onload =功能(EVT){
  如果(this.status == 200){
    VAR B64 = utf8_to_b64(this.responseText);
    VAR dataUri =数据:图像/ PNG; BASE64,'+ B64; //假设一个PNG图像    myImgElement.src = dataUri;
  }
};//将MDN:
// https://developer.mozilla.org/en-US/docs/Web/API/window.btoa
功能utf8_to_b64(STR){
    返回window.btoa(UNESCAPE(EN codeURIComponent(STR)));
}

画布

还有它由在画的&LT已加载数据的另一种选择;画布&GT; 字段。以此方式,用户将不能够右击相对于&所述图像(其中,画布被定位的区域); IMG&GT; 和数据的URI,其中查看图像属性面板时,用户将看到一个长的URI。

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.

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

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

I have two questions:

  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 asked for requests' details. Here they are.

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

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

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

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

解决方案

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.

Step 1: load the image data via JS

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

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

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.

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

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