2016-08-09 4 views
3

Я создаю backend API с Node/Express, которые получают данные от MongoDB. Фронт будет записан в «Реакт».Узел/Экспресс - Хороший подход к безопасной связи между клиентом/сервером

Я хотел был бы защитить клиент/сервер связи, но я не знаю как я должен думать о процессе.

Я вижу много учебников о passport или JWT, но это хорошо для аутентификации пользователя.

Я не знаю, является ли создание токена для каждого запроса на основе времени (например) хорошим подходом или слишком много для веб-приложения.

Но моя цель - защитить данные, потому что, даже если API является частным, вы можете легко узнать маршрут и попытаться выяснить, как подделать запрос с помощью Postman или что-то еще, чтобы отказаться от данных.

+3

На полузависимой ноте я считаю, что включение HTTPS - это первый шаг (вы можете получить бесплатные сертификаты из [LetsEncrypt] (https://letsencrypt.org/)), в дополнение к безопасному, проверенному и истинному пользователю/механизм проверки подлинности сеанса. Кроме того, вы захотите ознакомиться с информацией на сайте [OWASP] (https://www.owasp.org/index.php/Main_Page) для защиты от обычных атак, таких как XSS, CSRF и т. Д. – mscdex

+0

Спасибо ! Я включил промежуточное программное обеспечение с именем 'helmet', которое обрабатывает уже кучу атаки, такой как XSS, я думаю: https://www.npmjs.com/package/helmet Я посмотрю вашу ссылку. Мерси! Я буду использовать HTTPS точно, и я знаю о LetsEncrypt (названный cerbot, который я думаю сейчас), потому что я использовал его для своего личного сайта. Но я все еще в режиме dev (localhost), поэтому я сделаю это, когда будет реальный сервер. Благодарю. – Ragnar

ответ

2

Принятым стандартом является использование фиксированного API-ключа. Этот мир информации должен быть произвольно сгенерированной строкой, которую вы отправляете в каждом запросе в заголовке. Ваш сервер должен каждый раз проверять HTTP-запрос, чтобы увидеть, присутствует ли API-ключ в заголовке, а если он есть, тогда он должен проверять сохраненное значение в переменной среды (никогда не хранить API-ключ в коде).

Если API KEY становится скомпрометированным, вы можете легко обновить переменную env, и вы снова добры.

Теперь это решение будет бессмысленным без HTTPS-соединения, потому что любой сможет обнюхать трафик и увидеть API-ключ. Зашифрованное соединение является обязательным в этом случае.

Этот подход используется практически в каждой компании, которая имеет публичный API: Twitter, Facebook, Twilio, Google и т.д.

Google, например, имеет дополнительный этап, на котором они дают вам маркер, который истекает, но это будет более убивать в вашем случае: по крайней мере, в начале.

Следующий код является примером моей реализации проверки API KEY

app.use(function(req, res, next) { 

    // 
    // 1. Check if the APIKey is present 
    // 
    if(!req.headers.authorization) 
    { 
     return res.status(400).json(
      { 
       message: "Missing APIKey.", 
       description: "Unable to find the APIKey" 
      } 
     ); 
    } 

    // 
    // 2. Remove Basic from the beginning of the string 
    // 
    let noBasic = req.headers.authorization.replace('Basic ', ''); 

    // 
    // 3. Convert from base64 to string 
    // 
    let b64toString = new Buffer(noBasic, 'base64').toString("utf8"); 

    // 
    // 4. Remove the colon from the end of the string 
    // 
    let userAPIKey = b64toString.replace(':', ''); 

    // 
    // 5. Check if the APIKey matches the one on the server side. 
    // 
    if(userAPIKey != process.env.API_KEY) 
    { 
     return res.status(400).json(
      { 
       message: "APIKey don't match", 
       description: "Make sure what you are sending is what is in your server." 
      } 
     ); 
    } 

    // 
    // -> Go to the next stage 
    // 
    next() 

}); 

Вы можете проверить весь файл со всей реализацией hear.

+0

Спасибо, теперь все ясно. Всего 2 вопроса. 1) Вам нужно настроить что-то конкретное, чтобы обрабатывать клиентскую/серверную сторону HTTPS (за исключением сертификата на стороне сервера). Нужно ли настраивать nginx? 2) как вы управляете env.API_KEY. Это просто переменная env в системе, как, например, я бы выбрал «export EDITOR = emacs»? Также как мне управлять клиентской стороной? Тот же код, но наоборот (кодировка строки перед отправкой?). Спасибо – Ragnar

+0

Много вопросов :), так как раздел комментария имеет ограниченный символ, я отвечу на каждый вопрос в отдельном комментарии. –

+0

** HTTPS **: есть много способов сделать это, и все зависит от того, где вы собираетесь разместить свое приложение. Если вы размещаете его на Heroku, вам не нужно ничего делать на вашей стороне, вы включаете SSL на своей стороне, поэтому вам нужно сделать Google, как это сделать. Если вы сняли его самостоятельно, вы можете проверить, что в моей статье вы узнаете, как добавить SSL, что тривиально: https://github.com/davidgatti/IoT-Raw-Sockets-Examples/tree/master/Templates/NodeJS/tls. Все остальное зависит от вас :) –

1

Как я только что закончил auth часть моего приложения AngularJS. Ответ будет JWT и Паспорт, вы должны использовать отличные технологии для защиты ваших данных/API.

Если вы используете библиотеку JWT, это поможет вам удерживать заголовки http для авторизации.

Часть кода я использовал:

app.js

var jwt = require('express-jwt'); 

var auth = jwt({ 
    secret: config.jwt.secret, 
    userProperty: 'payload' 
}); 

app.use('/api/secret', auth, apiSecretRoutes); 

login.js

module.exports.login = function (req, res) { 
    if (!req.body.username || !req.body.password) { 
     return tools.sendJSONresponse(res, 400, { 
      message: 'All fields required!' 
     }); 
    } 

    passport.authenticate('local', function (err, user, info) { 
     var token; 
     if (err) { 
      return tools.sendJSONresponse(res, 404, err); 
     } 

     if (user) { 
      token = user.generateJwt(); 
      return tools.sendJSONresponse(res, 200, { 
       ok: true, 
       message: 'welcome ' + user.name, 
       token: token 
      }); 
     } else { 
      return tools.sendJSONresponse(res, 400, info); 
     } 
    })(req, res); 
}; 

пользователь.JS

userSchema.methods.generateJwt = function() { 
    var expiryDays = 1; 
    var expiry = new Date(); 
    expiry.setDate(expiry.getDate() + expiryDays); 

    return jwt.sign({ 
     _id: this._id, 
     username: this.username, 
     name: this.name, 
     exp: parseInt(expiry.getTime()/1000) 
    }, config.jwt.secret); 
}; 

Больше Refs:

+1

Спасибо. Но мне не нужна аутентификация пользователя с именем пользователя и паролем. Это больше внутренний API, где я хочу защитить запрос и данные. Ничего о том, что пользователь должен отслеживать использование моего приложения или запрещать доступ к какой-либо части приложения.Но, кстати, спасибо, потому что мне понадобится способ использовать этот тип авторизации рано или поздно;) – Ragnar

Смежные вопросы