#node.js #express #security #server #response
#node.js #экспресс #Безопасность #сервер #ответ
Вопрос:
Я использую express.js рамки для моего node.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');
var createUsers = require('./routes/users/createUsers');
var updateUsers = require('./routes/users/updateUsers');
var deleteUsers = require('./routes/users/deleteUsers');
var readUsers = require('./routes/users/readUsers');
var app = express();
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
var mysql = require("mysql");
//Database connection
app.use(function(req, res, next){
res.locals.connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'password',
database : 'project'
});
res.locals.connection.connect();
next();
});
// 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('/', index);
app.use('/createUsers', createUsers);
app.use('/updateUsers', updateUsers);
app.use('/deleteUsers', deleteUsers);
app.use('/readUsers', readUsers);
// 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.ejs');
});
var http = require('http');
module.exports = app;
var server = http.createServer(app);
server.listen(4000);
Это мой readUsers.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
//console.log("pending data");
res.locals.connection.query('SELECT id,name,email,username,address,phone,status FROM user', function (error, results, fields) {
if (error) throw error;
res.send(JSON.stringify(results));
});
});
module.exports = router;
Мой сервер прослушивается на порту 4000. Моя функция react frontend componentDidMount () используется axios.get("http://localhost:4000/readUsers")
для чтения данных из базы данных, и она работала хорошо.
Однако, если я напрямую введу http://localhost:4000/readUsers в моем браузере он будет напрямую подключаться к моей базе данных, считывать все пользовательские данные и отображать их в браузере. Я этого не хочу, потому что каждый может прочитать мои данные, если он знает этот адрес. Есть ли способ предотвратить эту проблему?
Комментарии:
1. браузер является http-клиентом, а
axios
также http-клиентом. Все, что вы делаете,axios
может быть сделано самим браузером. Единственное реальное решение — добавить процесс аутентификации перед рендерингом. Вы можете посмотреть: passportjs.org
Ответ №1:
Добавьте промежуточное программное обеспечение к вашему маршрутизатору. вот промежуточное программное обеспечение уровня маршрутизатора doc
У Express много промежуточного программного обеспечения, одно из них — промежуточное программное обеспечение уровня маршрута. Это промежуточное программное обеспечение обрабатывает все, что находится между пользователями и вашей функцией.
Вот пример, который я извлек из документации.
var app = express()
var router = express.Router()
// a middleware function with no mount path. This code is executed for every request to the router
router.use(function (req, res, next) {
console.log('Time:', Date.now())
next()
})
// a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
router.use('/user/:id', function (req, res, next) {
console.log('Request URL:', req.originalUrl)
next()
}, function (req, res, next) {
console.log('Request Type:', req.method)
next()
})
В вашем случае вы можете добавить некоторую проверку разрешений перед запросом. Обычно это ключ API, но это может быть что угодно, секретное слово в заголовке, секретный параметр, все.
Вот пример для вашего случая.
function isPermitted(req, res, next) {
var permitted = false;
// Your validation here, is your user permitted with this access or not.
if (permitted) {
next();
} else {
res.send('Sorry, you are not belong here.');
}
}
/* GET home page. */
router.get('/', isPermitted, function(req, res, next) {
//console.log("pending data");
res.locals.connection.query('SELECT id,name,email,username,address,phone,status FROM user', function (error, results, fields) {
if (error) throw error;
res.send(JSON.stringify(results));
});
});
Ответ №2:
Используйте POST вместо GET в качестве метода для запроса.
Комментарии:
1. это не предотвращает любой неавторизованный запрос. Вы можете сделать:
curl -XPOST http://localhost:4000/readUsers
и все равно найти всех пользователей.2. @Yanis-git да, я думаю, что axios.get() также небезопасен. Каждый может получить мои данные, если знает адрес
3. это не аксиомы, которые небезопасны, это то, как вы автоматически разрешаете пользователю выполнять запрос. Использование POST не защитит вас вообще. пожалуйста, обратитесь к моему комментарию и ответу septianw
4. Почему бы не поместить какой-то токен между обоими приложениями.
5. @Yanis-git Я думал, что вопрос заключается только в том, как избежать отображения ответа в браузере