我的项目有问题。我想为图片制作一个小的下载系统,所以我为Dim vPath As String
vPath = GetNewestDocument(Me!artNr)
'Returns path for pdf file, about:blank if there is no file.
If vPath = "about:blank" Then
Me!PDFBrowser.visible = True
Me.PDFBrowser.SourceDoc = vbNullString
Else
With Me.PDFBrowser
.OLETypeAllowed = acOLELinked
.SourceDoc = vPath
.SizeMode = acOLESizeStretch
End With
End If
制作了一个路由器。我有/download/:filename
中的图片,如果我请求/下载/使用像/userdata/${userId}/
这样的参数,它会在我的控制台中登录,但如果我使用了像test
这样的用户数据文件夹中存在的参数它将我重定向回用户的主路径:/ file / $ {userId}这里是我的代码:
app.js
Download.jpg
index.js路由器
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
const admin = require("./routes/admin");
import file from "./routes/file";
import download from "./routes/download";
const session = require("express-session");
var app = express();
app.set("trust proxy", 1);
app.use(session({
secret: "bla",
resave: false,
cookie: {
maxAge: 120000000
},
saveUninitialized: false
}));
function checkIfLoggedin(req,res,next){
if(!(req.originalUrl === "/") && !req.session.loggedIn){
res.redirect('/');
return;
}
next();
};
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(checkIfLoggedin);
app.use('/', index);
app.use("/admin", admin);
app.use("/file", file);
app.use("/download", download);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
file.js
var express = require('express');
var router = express.Router();
const bcrypt = require('bcrypt-nodejs');
var dbPassword;
import mysql from "mysql";
//
/* GET home page. */
router.get('/', function(req, res, next) {
if (req.session.user != undefined) {
res.redirect("/file/"+req.session.user.userId);
}
else{
res.render('index', {});
}
});
router.post('/', function(req,res,next) {
console.log("1");
const enteredUsername = req.body.username;
const enteredPassword = req.body.password;
const con = mysql.createConnection({
host: "localhost",
user: "user",
password: "pass",
database: "db"
});
con.query('SELECT * FROM users WHERE username = ?;', [`${enteredUsername}`], (error, results, fields) => {
if (results.length > 0) {
console.log("2");
console.log(error);
let dbPassword = results[0].password;
bcrypt.compare(enteredPassword, dbPassword, (err,response) => {
console.log(err);
console.log(response);
console.log("3");
if (response == true) {
req.session.user = {
userId: results[0].userId,
username: results[0].username,
isAdmin: results[0].isAdmin,
};
req.session.loggedIn = true;
console.log("file");
if (req.session.user.isAdmin) {
res.redirect("/admin");
}
else{
res.redirect("/file/" + req.session.user.userId);
}
}
else{
req.session.loggedIn = false;
console.log("false");
res.send("Falsches Passwort");
}
});
}
else{
res.send("Falsche Daten");
}
});
});
router.get("/logout", (req,res,next) => {
if (req.session.user.userId) {
req.session.destroy();
res.redirect("/");
}
});
module.exports = router;
download.js
import express from "express";
import fs from "fs";
const router = express.Router();
const userDataPath = "/srv/www/www.precode.tech/www/userdata/";
router.get("/:userId", (req,res,next) => {
//console.log(req.params.userId == req.session.user.userId);
if (req.params.userId == req.session.user.userId) {
const userDataFiles = fs.readdirSync(userDataPath+req.session.user.userId);
res.render("file", {files : userDataFiles, user: req.session.user});
}
else{
res.status(403).render("unauthorized");
}
//res.send(`${req.params.userId} ${req.session.user.userId}`);
});
/*router.get("/:userId/download/:filename", (req,res,next) => {
console.log(req.params.filename);
if (req.params.userId == req.session.user.userId) {
let filePath = `${__dirname}/../userdata/${req.session.user.userId}/`;
res.download(filePath, req.params.filename);
next();
};
});*/
export default router;
如果您有想法或看到问题,那将是非常好的。 谢谢:))
编辑:它不应该重定向到用户的基本路径,下载的get请求应该总是在console.log项目
答案 0 :(得分:0)
我没有找到这个缺陷,但让我们清理代码并修复中间件附加序列(至少我看到会话中间件后附加的cookie解析器,我怀疑只有那部分)并检查。
但是,让我们检查我的代码审查/清理。
真的希望它有所帮助。
app.js
:
const express = require('express');
const path = require('path');
//const favicon = require('serve-favicon');
const logger = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const session = require("express-session");
const mysql = require('mysql');
const db = mysql.createConnection({
host: "localhost",
user: "user",
password: "pass",
database: "db"
});
const app = express();
app.set("trust proxy", 1);
// set view engine and renderer
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// serve static files
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); // no need for it since express static will serve all static files in public folder
app.use(express.static(path.join(__dirname, 'public')));
// connect morgan to profile requests
app.use(logger('dev'));
// parse cookies first
app.use(cookieParser());
// then handle session
app.use(session({
secret: "bla",
resave: false,
cookie: {
maxAge: 120000000
},
saveUninitialized: true
}));
// handle requests data
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use((req, res, next) => {
req.db = db; // attach db connection to request context
next();
});
// public routes that does not need auth check
app.use('/', require('./routes/index'));
const checkIfLoggedin = (req, res, next) => {
if (!req.session.loggedIn) {
return res.redirect('/');
}
res.locals.user = req.session.user;
next();
};
// internal routes that needs auth check
app.use(
'/admin',
checkIfLoggedin,
require('./routes/admin'));
app.use(
'/files',
checkIfLoggedin,
require('./routes/files'));
/* no need for this route, it's covered in files.js
app.use(
'/download',
checkIfLoggedin,
download);
*/
// catch 404 and forward to error handler
app.use((error, req, res, next) => {
if (error) return next(error);
const err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use((error, req, res, next) => {
// set locals, only providing error in development
res
.status(error.status || 500)
.render('error', {
message: error.message,
error: req.app.get('env') === 'development' ? error : {}
});
});
module.exports = app;
routes/index.js
:
const express = require('express');
const router = express.Router();
const logger = require('winston');
const bcrypt = require('bcrypt-nodejs');
const _ = require('lodash'); // install it: npm i --save lodash
/* GET home page. */
router.get('/', (req, res) => {
if (_.get(req, 'session.user.userId')) {
return res.redirect("/files/" + req.session.user.userId);
}
res.render('index', {});
});
router.post('/auth', (req, res, next) => {
const {username, password} = req.body;
const db = req.db;
const query = 'SELECT * FROM users WHERE username = ? LIMIT 1';
const fields = [username];
db.query(
query,
fields,
(err, result) => {
if (err) {
logger.error(err);
const error = new Error('System fehler');
return next(error);
}
const user = _.get(result, '0');
if (!user) {
req.session.loggedIn = false;
const error = new Error('Benutzer nicht gefunden');
error.status = 403;
return next(error);
}
bcrypt.compare(password, user.password,
(err, isEqual) => {
if(err || !isEqual) {
if (err) logger.error('Error in password compare:', err);
const error = new Error('Passwort ungültig');
error.status = 403;
return next(error);
}
req.session.user = _.pick(user, ['id', 'userId', 'username', 'isAdmin']);
req.session.loggedIn = true;
if (user.isAdmin) {
return res.redirect("/admin");
}
res.redirect("/files/" + user.userId);
});
});
});
router.get("/logout", (req, res) => {
// simply destroy session and redirect,
// no need for session check
req.session.destroy();
res.redirect("/");
});
module.exports = router;
routes/files.js
:
const express = require('express');
const router = express.Router();
const logger = require('winston');
const fs = require('fs');
const path = require('path');
const async = require('async');
const userDataPath = path.join(__dirname, '..', 'userdata');
// no need to check userId with session.user.userId
// since middleware attached in app.js will guard this route
// and redirect user to '/'
router.get('/:userId', (req, res, next) => {
if(req.params.userId != req.session.user.userId) {
const error = new Error("You cannot access other user's files");
error.status = 403;
return next(error);
}
const directory = path.join(userDataPath, req.params.userId);
logger.info('Reading directory:', directory);
fs.readdir(
directory,
(err, entries) => {
if (err) {
logger.error(err);
const error = new Error('System error');
return next(error);
}
const directories = [];
const files = [];
async.eachLimit(
entries, 10,
(entry, done) => {
fs.stat(path.join(dir, entry), (error, stat) => {
if (stat.isFile()) files.push(entry);
if (stat.isDirectory()) directories.push(entry);
done();
});
},
() => {
res.render("files", {
directories,
files
});
});
});
});
router.get('/:userId/download/:filename', (req, res, next) => {
if(req.params.userId != req.session.user.userId) {
const error = new Error("You cannot access other user's files");
error.status = 403;
return next(error);
}
res.download(path.join(userDataPath, req.params.userId, req.params.filename));
});
module.exports = router;
P.S。如果它在nginx,apache等后面工作,请确保无法公开访问userdata文件夹。