Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ajax 在Angular和JWT中下载文件_Ajax_Angularjs_Node.js_Express_Jwt - Fatal编程技术网

Ajax 在Angular和JWT中下载文件

Ajax 在Angular和JWT中下载文件,ajax,angularjs,node.js,express,jwt,Ajax,Angularjs,Node.js,Express,Jwt,TL;DR 如何使用Angular和JWT身份验证下载/保存文件,而不在浏览器中留下令牌痕迹 我的Angular/Node应用程序通过HTTPS进行安全保护,并使用JWT进行身份验证。JWT存储在sessionStorage中,并将所有AJAX请求的授权头字段传递给服务器 我需要应用程序中的功能来下载文件,以便浏览器自动保存文件(或显示保存位置的弹出窗口等) 它应该在任何可以运行Angular的浏览器中理想地工作 我看了以下几点: AJAX请求。这不起作用,因为固有的安全措施阻止浏览器在本地保

TL;DR

如何使用Angular和JWT身份验证下载/保存文件,而不在浏览器中留下令牌痕迹


我的Angular/Node应用程序通过HTTPS进行安全保护,并使用JWT进行身份验证。JWT存储在sessionStorage中,并将所有AJAX请求的授权头字段传递给服务器

我需要应用程序中的功能来下载文件,以便浏览器自动保存文件(或显示保存位置的弹出窗口等)

它应该在任何可以运行Angular的浏览器中理想地工作

我看了以下几点:

AJAX请求。这不起作用,因为固有的安全措施阻止浏览器在本地保存文件

在Cookie中传递JWT-Cookie是我想要避免使用的东西,因此使用sessionStorage的原因

在查询字符串中传递JWT,但这意味着它将被记录在服务器日志中,更重要的是可以在浏览器历史记录中看到

iframe,其中包含发布数据的表单。无法使用此方法设置标题


还有其他选择吗?

iframe方法已关闭。只需要将服务器设置为从帖子主体而不是查询字符串接受JWT

使用iframe并不是最优雅的解决方案,但它似乎满足了需求。以下是我使用的指令:

.directive('fileDownload', function () {
    return {
        restrict: 'A',
        replace: false,
        template: "<iframe style='position:fixed;display:none;top:-1px;left:-1px;' />",
        link: function (scope, element) {
            element.click(function() {
                var iframe = element.find('iframe'),
                    iframeBody = $(iframe[0].contentWindow.document.body),
                form = angular.element("<form method='POST' action='/my/endpoint/getFile'><input type='hidden' name='foo' value='bar' /><input type='hidden' name='access_token' value='" + scope.access_token + "' /></form>");

                iframeBody.append(form);
                form.submit();
            });
        }
    }
});

在网上搜寻解决方案,但没有找到令人满意的解决方案后,我终于找到了一个使用来自世界各地的零碎建议的解决方案

希望这能帮助寻找安全解决方案的人

我使用了Bagofjuice描述的iframe解决方案,但使用了jquery.filedownload插件(请参阅)

这是我为确保此请求而做的:

当用户单击下载按钮或链接时,我从服务器请求一个新令牌(为此创建了一个专用的服务器API调用),并将其作为查询字符串附加到文件下载url,然后使用filedownload插件下载文件。请注意,此令牌的过期时间非常短,因为它被立即用于下载文件,并且不应使用多次

然后在服务器端,当令牌通过查询参数到达时,我会提供响应,并立即使令牌过期(此外还有过期时间,以消除最小的窗口被利用)


即时过期的工艺可能会有所不同。我使用的方法是,当我创建这个临时令牌时,我将它存储在内存缓存中,第一次使用时,我将它从缓存中删除。如果它在缓存中不存在,当我通过请求接收它时,我认为它是无效的令牌。这可以防止令牌通过查询参数被多次使用。因此,这是记录在服务器端日志中还是在浏览器上留下痕迹并不重要。对于web服务器场,您可以轻松地将其存储在分布式缓存中。

我认为答案可能在这里:即,稍微修改服务器,使其不会在auth头中使用JWT,如果未找到,则从正文中读取(备份以前使用查询字符串)。可能重复
if (req.body && req.body.hasOwnProperty('access_token')) {
    req.headers.authorization = 'Bearer ' + req.body.access_token;
}