上传文件并请求受保护的下载node.js

时间:2018-04-24 05:09:52

标签: node.js express directory protected multer

我有一个使用node.js,express和multer上传文件的系统,这些文件存储在一个静态目录中。我想要的是将它们存储在服务器上,并且只有在我登录后才能看到它们。

问题:

我上传的系统很好,但我需要保护目录/files/documents/hv.pdf中的文件,因为每当我输入文件打开的URL时,浏览器会保存历史记录,这是不应该发生的事情,如果用户尚未登录,我该如何避免访问?

我正在尝试运行一个中间件,如果url的字符串带有/ files文件夹的名称,那么如果我没有放置文件名或者添加/ files之类的其他名称,这很有趣/document/test.txt它工作但不是当我访问静态文件夹中的链接时,我认为它是缓存,但它绝对不是那个

此中间件

module.exports = (req,res,next)=>{
    let regex = /^\/files\/.*$/;
    if (!regex.test(req.url)) { return next(); }

    // for test
    req.session.user = {name:"thaylor"}; //comment for not session
    //fin for test

    if(req.session.user){
        next();
    }else{
        res.end('You are not allowed!');
    }
}

更新,此解决方案2018-04-2017

用于获取根路径和受保护路由的中间件app.js

const protectedfile = require("./controllers/protectedfile");

app.use(function(req, res, next) {
    req.rootPath = __dirname;
    next();
});

app.use('/files', protectedfile);
app.use('/files', express.static(path.join(__dirname, 'files')) );

此文件控制器/ protectedfile.js

const path = require('path'); 
module.exports = (req,res,next)=>{
    if(!req.session.user){
        res.send("Route protected");
    }else{          
        let file = path.join(req.rootPath, req.originalUrl);  
        res.download(file, function (err) {
            if (err) {
                console.log("Error");
                console.log(err);
            } else {
                console.log("success"); 
            }        
        });       
    }
}

感谢所有

2 个答案:

答案 0 :(得分:0)

var express = require("express");
var path = require( "path" );
var app = express();

app.use( '/upload', isLoggedIn, express.static( path.join( __dirname, '**your upload folder name**' ) ) );

app.listen( 3000 );

//Use this code if you are using passport.js for authentication mech.
function isLoggedIn(req, res, next) {
    if (req.user) {
        next();
    } else {
        res.redirect('/login');
    }
}

//Use this code for custom sign in implementation
function isLoggedIn(req, res, next) {
    //check if user is logged in
    // your business logic goes here
    if ( condition ) {
        next();
    } else {
        res.redirect('/login');
    }
}

每次调用localhost:3000 / upload / *都会通过isLoggedIn函数执行此操作。

答案 1 :(得分:0)

在我深入了解细节之前,要记住的一件事是Express.js框架中的一切被视为一块中间件。所以你的代码很重要(即你的app.use按顺序连接的方式)。每次客户端访问您的应用程序时,都会从app.js文件的顶部开始,直到可以返回某些内容。

首先,静态路由意味着通过此给定路径(文件夹)传递的内容是静态的。通常,在app.js文件的顶部,有:

app.use(express.static('./public', options));

在上面的代码中,文件夹'public'被设置为静态。这是放入此文件夹的任何内容(包括放入其子文件夹中的文档)对公众完全透明,因此您无需指定放入此文件夹的内容。当客户端尝试向您的服务器发出HTTP请求时,Express将扫描该文件夹并在找到所请求的文件后返回该文档;如果没有,那么它将通过您的下一个app.use

您可以分配多个静态路由。例如,如果您现在在上面的代码之后附加了以下代码:

app.use(express.static('./file', options));

您的服务器现在将在“./public”路径中找不到后,扫描名为“file”后面的文件夹,并尝试查找所请求的文档。基本上,做同样的事情。

通过将上面的代码替换为:

,您可以玩这个技巧
app.use('/file', checkIfTheUserHaveLogIn);
app.use('/file', express.static('./file', options));

或一行:

app.use('/file', checkIfTheUserHaveLogIn, express.static('./file', options));

在这里,我使用'/file'作为app.use中的第一个参数来指定URL中必须匹配的特殊路径。注意,checkIfTheUserHaveLogIn是一个中间件函数,用作控制器(函数)来决定是否允许客户端访问下一级中间件(通过调用next()),即express.static('./file', options) 。如果客户端未被授予该权限,您可以将客户端重定向到登录页面或在checkIfTheUserHaveLogIn中执行其他操作。

在您的代码中,您设置路由器以筛选出“/ file”路由路径以执行身份验证。但是,因为中间件的顺序如何重要。它实际上首先触发静态路由器,并且可以找到该文档,以便该文件已经返回到所请求的客户端。实际上你的中间件从未到过。为了避免它,只需按照我之前的操作,设置另一个静态路由并指向另一个文件夹(不能是第一个透明静态路由器下的子文件夹,即不在我的示例中的./public下)。然后它应该完美。

希望我的解释澄清你的问题。