我正在开发一个单页面,客户端使用 Javascript+AngularJS,服务器端使用 Spring MVC + Spring Security OAuth2。 Spring MVC 充当来自页面的任何 AJAX 请求的 REST 控制器。
对于授权,脚本会随每个 AJAX 请求发送“Authorization: Bearer ...”标头。当请求少量数据时,这很有效。 要下载 XML 文件(导出用户数据),我使用 OAuth2 标头通过 AJAX 下载它们,并创建一个 Blob 以允许在浏览器中保存文件:
var blob = new Blob([data.data], {'type': "text/xml"});
var a = document.createElement("a");
a.href = window.URL.createObjectURL(blob);
a.download = "downloaded-file-" + new Date().toISOString() + ".xml";
a.click();
这种方法有效,但是
那么,问题来了:有没有更好的OAuth2授权下载文件的方法呢? Javascript 不允许在进行重定向时指定标头,并且 OAuth 不允许通过 URL 参数指定授权令牌。我正在考虑其中一个
如果有人遇到类似问题,可以分享一下解决这个问题的方法吗?
您现在可以使用文件系统 API 流式传输下载文件。您可以通过在开始下载之前打开文件对话框来创建 WriteableStream,然后使用 URL 中的可读流。这不会显示在浏览器的下载列表中,也不会显示下载进度,但它避免了为 blob 下载和分配内存的需要。
如果我是你,我会选择饼干——这样可以省去所有麻烦。我最近写了一些博客来展示它是多么容易(例如 https://spring.io/blog/2015/01/20/the-resource-server-angular-js-and-spring-security-part-iii )。人们太沉迷于“无状态”应用程序了。
事实证明,在 spring-security-oauth2 2.0.7.RELEASE 中这非常容易:
只需将访问令牌作为
access_token
请求参数传递即可:
window.open("service/export?access_token=" + access_token);
现在,这将在下载历史记录中以明文形式显示访问令牌,因此为了确保适当的安全性,应正确实施“注销”选项,否则下载必须以“表单发布”的形式完成。