如何将身份验证标头添加到 $window.open

Posted

技术标签:

【中文标题】如何将身份验证标头添加到 $window.open【英文标题】:how to add authentication header to $window.open 【发布时间】:2014-06-02 01:13:50 【问题描述】:

我有 angularjs 应用程序,用户在其中输入保存到数据库的数据,然后在服务器端将其编译为 pdf 文件。所有访问都需要适当的身份验证标头。填充所需数据后,用户按下按钮保存数据,然后检索 pdf 文件。最理想的是,我在我的 angularjs 应用程序中调用 $window.open(url_generating_pdf)。这很好用并在另一个窗口中打开,但是如何将身份验证标头添加到此 $window 请求中?据我了解,我无法下载 pdf 并用 ajax 打印,所以我错过了这个身份验证。或者还有其他方法可以从服务器调用url,并在另一个窗口中打开文件?

【问题讨论】:

【参考方案1】:

我认为我应该用正确且安全的答案来更新这个老问题。

您不能在window.open 执行的HTTP GET 请求中添加任何标头

发出经过身份验证的请求的安全方法是将身份验证令牌设置到请求标头中,并避免将其暴露在 URL 中,正如我之前的回答所建议的那样(我从那以后学到了一些东西然后)。

要使用 AngularJS 从经过身份验证的服务器下载 PDF(或任何其他二进制数据),您应该:

    向资源 sending the authentication token in a header 发出 HTTP GET 请求,将其 responseType 设置为二进制数据类型,例如 blobarraybuffer。 Download the binary data in a file 使用浏览器中的“另存为”对话框,通常为二进制数据创建一个下载链接并单击它。

我希望这个答案能够消除对此问题的疑虑,并提供一种从经过身份验证的 REST API 下载资源的安全方式。

【讨论】:

【参考方案2】:

我认为您可以在 URL 中添加此身份验证参数并在服务器端执行 GET

//Add authentication headers as params
var params = 
    access_token: 'An access_token',
    other_header: 'other_header'
;

//Add authentication headers in URL
var url = [url_generating_pdf, $.param(params)].join('?');

//Open window
window.open(url);

【讨论】:

最后,我解决了这个问题。我为 pdf 制作了标准的 $http.get。我返回短暂的 url 以获取允许使用 window.open 到新窗口进行未经身份验证的下载的调用。您的解决方案也可以使用 @hmartos 在 URL 中发送您的令牌会将其暴露给任何窃听您发送到服务器的数据包的人。该 URL 从未加密,因此任何人都可以看到。注意不要暴露你的令牌。用甘道夫的话来说:“保守秘密,保证安全。” 感谢@JFarr 的建议,您知道如何将令牌传递给 API 并保密吗? 经过一番研究,我发现通过 https 的查询字符串是安全的,无论如何在 URL 中发送任何敏感数据都不是一个好主意(请参阅***.com/questions/323200/…)。所以我认为最好的选择是在请求头中发送这个令牌(***.com/questions/187655/are-https-headers-encrypted) 这不能回答问题。令牌作为查询参数添加,而不是遵守将其添加为标头的原始条件。【参考方案3】:

您可以使用标头和 responseType 中的令牌调用您的安全 api,以 blob 并以下列方式解析您的响应,并希望您能在 chrome 和 firefox 的浏览器中查看您的 pdf。

var ieEDGE = navigator.userAgent.match(/Edge/g);
        var ie = navigator.userAgent.match(/.NET/g); // IE 11+
        var oldIE = navigator.userAgent.match(/MSIE/g);

        var blob = new window.Blob([response],  type: 'application/pdf' );

        if (ie || oldIE || ieEDGE) 
          window.navigator.msSaveBlob(blob, fileName);
        
        else 
          var fileURL = URL.createObjectURL(blob);
          window.open(fileURL);
        

【讨论】:

以上是关于如何将身份验证标头添加到 $window.open的主要内容,如果未能解决你的问题,请参考以下文章

如何将标头身份验证承载中的令牌发送到浏览器

如何在传入的http请求标头中添加授权令牌[关闭]

在 ember-file-upload 的请求标头中添加身份验证令牌

如何在 Spring Security 中为所有请求添加 jwt 身份验证标头?

如何将 CORS 标头添加到 401/403 响应?

如何在高速公路客户端工具中添加基本身份验证标头