2016-08-09 10 views
3

Ich baue eine Backend-API mit Node/Express, die die Daten von einer MongoDB erhalten. Die Vorderseite wird in React geschrieben.Node/Express - Guter Ansatz für sichere Kommunikation zwischen Client/Server

Ich möchte die Kommunikation Client/Server sichern, aber ich weiß nicht, wie ich über den Prozess denken muss.

Ich sehe viele Tutorial über passport oder JWT, aber das ist gut für eine Benutzerauthentifizierung.

Ich weiß nicht, ob das Erstellen eines Tokens für jede Anfrage basierend auf der Zeit (zum Beispiel) ein guter Ansatz ist oder zu aufwendig für eine Web-App.

Aber mein Ziel ist es, die Daten zu sichern, denn selbst wenn die API privat ist, können Sie leicht die Route herausfinden und herausfinden, wie Sie eine Anfrage mit Postman oder etwas anderem fälschen können, um die Daten zu verschrotten.

+3

Bei einer semi-verwandten Anmerkung, denke ich, die Aktivierung von HTTPS ist der erste Schritt (Sie können kostenlose Zertifikate von [LetsEncrypt] (https://letsencrypt.org/)), zusätzlich zu einem sicheren, bewährten und echten Benutzer/Sitzungsauthentifizierungsmechanismus. Außerdem sollten Sie sich die Informationen auf der [OWASP] -Seite (https://www.owasp.org/index.php/Main_Page) zum Schutz vor häufigen Angriffen wie XSS, CSRF usw. durchlesen. – mscdex

+0

Vielen Dank ! Ich habe die Middleware mit dem Namen 'helm' aktiviert, die bereits eine Reihe von Angriffen wie XSS behandelt. Ich denke: https://www.npmjs.com/package/helmet Ich werde auf Ihren Link schauen. Merci! Ich werde HTTPS sicher verwenden und ich weiß über LetsEncrypt (benannt cerbot denke ich jetzt), weil ich es für meine persönliche Website verwendet habe. Aber ich bin immer noch im Dev-Modus (localhost), also werde ich es tun, wenn der echte Server hochgefahren ist. Vielen Dank. – Ragnar

Antwort

2

Der akzeptierte Standard besteht darin, einen festen API KEY zu verwenden. Dieser Informationsfrieden sollte eine zufällig generierte Zeichenfolge sein, die Sie in jeder Anfrage in der Kopfzeile senden. Ihr Server muss die HTTP-Anfrage jedes Mal überprüfen, um zu sehen, ob der API KEY in der Kopfzeile vorhanden ist, und wenn dies der Fall ist, muss er den gespeicherten Wert in der Umgebungsvariable überprüfen (niemals den API KEY im Code speichern).

Wenn der API-KEY kompromittiert wird, können Sie die env-Variable einfach aktualisieren, und Sie sind wieder gut.

Jetzt ist diese Lösung ohne eine HTTPS-Verbindung sinnlos, weil jeder in der Lage sein wird, den Verkehr zu schnüffeln und den API KEY zu sehen. Eine verschlüsselte Verbindung ist in diesem Fall ein Muss.

Dieser Ansatz wird von nahezu jedes Unternehmen verwendet, die eine öffentliche API hat: Twitter, Facebook, Twilio, Google usw.

Google zum Beispiel hat einen zusätzlichen Schritt, wo sie Ihnen ein Token geben, die verfallen, aber das wird in deinem Fall ein Overkill sein: zumindest am Anfang.

Der folgende Code ist ein Beispiel für meine Implementierung einer API-Key-Überprüfung

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() 

}); 

Sie die gesamte Datei hear mit der ganzen Umsetzung überprüfen können.

+0

Danke, es ist jetzt wirklich klar. Nur 2 Fragen. 1) Müssen Sie etwas speziell für die HTTPS-Client/Server-Seite einrichten (außer das Zertifikat auf der Server-Seite). Muss ich nginx einrichten? 2) wie verwalten Sie die env.API_KEY. Es ist einfach eine env-Variable im System, wie ich zB export EDITOR = emacs setzen würde? Wie kann ich die Client-Seite verwalten? Der gleiche Code, aber umgekehrt (Codierung der Zeichenfolge vor dem Senden?). Danke – Ragnar

+0

Viele Fragen :) Da der Kommentar-Bereich begrenzt Char hat, werde ich jede Frage in einem getrennten Kommentar beantworten. –

+0

** HTTPS **: Es gibt viele Möglichkeiten, dies zu tun, und alles hängt davon ab, wo Sie Ihre App hosten werden. Wenn Sie es auf Heroku hosten, müssen Sie nichts auf Ihrer Seite tun, Sie aktivieren SSL auf ihrer Seite, also müssen Sie googeln, wie es dort geht. Wenn du es selbst aufgenommen hast, kannst du in meinem Artikel nachlesen, wie du SSL hinzufügen kannst. Das ist trivial: https://github.com/davidgatti/IoT-Raw-Sockets-Examples/tree/master/Templates/NodeJS/tls. Alles andere hängt von Ihnen ab :) –

1

Wie ich gerade den Auth-Teil meiner AngularJS Anwendung beendet. Die Antwort lautet JWT und Passport, Sie sollten die großen Technologien verwenden, um Ihre Daten/API zu schützen.

Wenn Sie die JWT-Bibliothek verwenden, können Sie die HTTP-Köpfe für die Autorisierung halten.

Einige der Code, den ich verwendet:

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); 
}; 

Benutzer.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); 
}; 

Mehr Refs:

+1

Danke. Aber ich brauche keine Benutzerauthentifizierung mit Benutzername und Passwort. Es ist mehr eine interne API, wo ich die Anfrage und die Daten sichern möchte. Nichts über die Berechtigung eines Benutzers, den Überblick über seine Nutzung meiner App zu behalten oder den Zugriff auf einen Teil der App zu verweigern.Aber danke übrigens, denn ich werde früher oder später einen Weg finden, diese Art von Auth zu benutzen;) – Ragnar

Verwandte Themen