Αποστολή δεδομένων από το ένα μέρος στο άλλο; Για τη δική σας ηρεμία και την προστασία των χρηστών σας, θα πρέπει να το ασφαλίσετε με το JWT.

Όταν δημιουργείτε μια εφαρμογή, είναι ζωτικής σημασίας να προστατεύετε ευαίσθητα δεδομένα από μη εξουσιοδοτημένη πρόσβαση. Πολλές σύγχρονες εφαρμογές ιστού, κινητών και cloud χρησιμοποιούν REST API ως κύριο μέσο επικοινωνίας. Ως αποτέλεσμα, είναι ζωτικής σημασίας ο σχεδιασμός και η ανάπτυξη backend API με την ασφάλεια στην πρώτη γραμμή.

Μια αποτελεσματική προσέγγιση για την εξασφάλιση ενός REST API περιλαμβάνει τα JSON Web Tokens (JWT). Αυτά τα διακριτικά προσφέρουν έναν ισχυρό μηχανισμό για έλεγχο ταυτότητας και εξουσιοδότηση χρήστη, συμβάλλοντας στην προστασία των προστατευμένων πόρων από την πρόσβαση κακόβουλων παραγόντων.

Τι είναι τα JSON Web Tokens;

JSON Web Token (JWT) είναι ένα ευρέως χρησιμοποιούμενο πρότυπο ασφαλείας. Παρέχει μια συνοπτική, αυτόνομη μέθοδο ασφαλούς μετάδοσης δεδομένων μεταξύ μιας εφαρμογής πελάτη και ενός συστήματος υποστήριξης.

instagram viewer

Ένα REST API μπορεί να χρησιμοποιεί JWT για την ασφαλή αναγνώριση και έλεγχο ταυτότητας των χρηστών όταν υποβάλλουν αιτήματα HTTP για πρόσβαση σε προστατευμένους πόρους.

Ένα JSON Web Token αποτελείται από τρία διακριτά μέρη: την κεφαλίδα, το ωφέλιμο φορτίο και την υπογραφή. Κωδικοποιεί κάθε μέρος και τα ενώνει χρησιμοποιώντας μια τελεία (".").

Η κεφαλίδα περιγράφει τον κρυπτογραφικό αλγόριθμο που χρησιμοποιείται για την υπογραφή του διακριτικού, ενώ το ωφέλιμο φορτίο περιέχει δεδομένα για τον χρήστη και τυχόν πρόσθετα μεταδεδομένα.

Τέλος, η υπογραφή, που υπολογίζεται χρησιμοποιώντας την κεφαλίδα, το ωφέλιμο φορτίο και το μυστικό κλειδί, διασφαλίζει την ακεραιότητα και την αυθεντικότητα του διακριτικού.

Με τα βασικά των JWT εκτός λειτουργίας, ας δημιουργήσουμε ένα Node.js REST API και ας εφαρμόσουμε JWT.

Ρυθμίστε μια εφαρμογή Express.js και μια βάση δεδομένων MongoDB

Θα μάθετε εδώ πώς να δημιουργήσετε έναν απλό έλεγχο ταυτότητας REST API που χειρίζεται τόσο τη λειτουργικότητα εγγραφής όσο και σύνδεσης. Μόλις η διαδικασία σύνδεσης πιστοποιήσει την ταυτότητα ενός χρήστη, θα πρέπει να μπορεί να κάνει αιτήματα HTTP σε μια προστατευμένη διαδρομή API.

Μπορείτε να βρείτε τον κωδικό του έργου σε αυτό Αποθετήριο GitHub.

Για να ξεκινήσετε, δημιουργήστε έναν διακομιστή ιστού Expressκαι εγκαταστήστε αυτά τα πακέτα:

npm εγκατάσταση cors dotenv bycrpt mongoose cookie-parser crypto jsonwebtoken mongodb

Επόμενο, δημιουργήστε μια βάση δεδομένων MongoDB ή διαμορφώστε ένα σύμπλεγμα MongoDB στο cloud. Στη συνέχεια, αντιγράψτε τη συμβολοσειρά σύνδεσης βάσης δεδομένων, δημιουργήστε ένα .env αρχείο στον ριζικό κατάλογο και επικολλήστε τη συμβολοσειρά σύνδεσης:

CONNECTION_STRING="συμβολοσειρά σύνδεσης"

Διαμορφώστε τη σύνδεση βάσης δεδομένων

Δημιούργησε ένα νέο utils/db.js αρχείο στον ριζικό κατάλογο του φακέλου του έργου σας. Σε αυτό το αρχείο, προσθέστε τον ακόλουθο κώδικα για να δημιουργήσετε τη σύνδεση της βάσης δεδομένων χρησιμοποιώντας το Mongoose.

συνθ μαγκούστα = απαιτώ('μαγκούστα');

συνθ connectDB = ασυγχρονισμός () => {
δοκιμάστε {
αναμένω mongoose.connect (process.env. CONNECTION_STRING);
κονσόλα.κούτσουρο("Συνδέθηκε στο MongoDB!");
} σύλληψη (λάθος) {
κονσόλα.λάθος("Σφάλμα σύνδεσης στο MongoDB:", λάθος);
}
};

μονάδα μέτρησης.exports = connectDB;

Ορίστε το μοντέλο δεδομένων

Καθορίστε ένα απλό σχήμα δεδομένων χρήστη χρησιμοποιώντας το Mongoose. Στον ριζικό κατάλογο, δημιουργήστε ένα νέο model/user.model.js αρχείο και προσθέστε τον παρακάτω κώδικα.

συνθ μαγκούστα = απαιτώ('μαγκούστα');

συνθ userSchema = νέος μαγκούστα. Σχήμα({
όνομα χρήστη: Σειρά,
Κωδικός πρόσβασης: {
τύπος: Σειρά,
απαιτείται: αληθής,
μοναδικός: αληθής,
},
});

συνθ Χρήστης = mongoose.model("Χρήστης", userSchema);
μονάδα μέτρησης.exports = Χρήστης;

Καθορίστε τους ελεγκτές για τις διαδρομές API

Οι λειτουργίες του ελεγκτή θα διαχειρίζονται την εγγραφή και τη σύνδεση. αποτελούν σημαντικό μέρος αυτού του δείγματος προγράμματος. Στον ριζικό κατάλογο, δημιουργήστε ένα controllers/userControllers.js αρχείο και προσθέστε τον ακόλουθο κώδικα:

  1. Καθορίστε τον ελεγκτή εγγραφής χρήστη.
    συνθ Χρήστης = απαιτώ("../models/user.model");
    συνθ bcrypt = απαιτώ('bcrypt');
    συνθ {genereToken} = απαιτώ("../middleware/auth");

    exports.registerUser = ασυγχρονισμός (απαιτ., ανταπ.) => {
    συνθ { όνομα χρήστη, κωδικός πρόσβασης } = req.body;

    δοκιμάστε {
    συνθ κατακερματισμός = αναμένω bcrypt.hash (κωδικός πρόσβασης, 10);
    αναμένω User.create({ όνομα χρήστη, Κωδικός πρόσβασης: hash });
    res.status(201).στείλετε({ μήνυμα: "Ο χρήστης εγγράφηκε με επιτυχία" });
    } σύλληψη (λάθος) {
    κονσόλα.log (σφάλμα);
    res.status(500).στείλετε({ μήνυμα: 'Παρουσιάστηκε σφάλμα!! ' });
    }
    };

    Αυτό το απόσπασμα κώδικα κατακερματίζει τον παρεχόμενο κωδικό πρόσβασης χρησιμοποιώντας το bcrypt και, στη συνέχεια, δημιουργεί μια νέα εγγραφή χρήστη στη βάση δεδομένων, αποθηκεύοντας το όνομα χρήστη και τον κατακερματισμένο κωδικό πρόσβασης. Εάν η εγγραφή είναι επιτυχής, στέλνει μια απάντηση με ένα μήνυμα επιτυχίας.
  2. Ορίστε έναν ελεγκτή σύνδεσης για τη διαχείριση της διαδικασίας σύνδεσης χρήστη:
    exports.loginUser = ασυγχρονισμός (απαιτ., ανταπ.) => {
    συνθ { όνομα χρήστη, κωδικός πρόσβασης } = req.body;

    δοκιμάστε {
    συνθ χρήστης = αναμένω User.findOne({ όνομα χρήστη });

    αν (!χρήστης) {
    ΕΠΙΣΤΡΟΦΗ res.status(404).στείλετε({ μήνυμα: 'Ο χρήστης δεν βρέθηκε' });
    }

    συνθ κωδικός Ταίριασμα = αναμένω bcrypt.compare (password, user.password);

    αν (!passwordMatch) {
    ΕΠΙΣΤΡΟΦΗ res.status(401).στείλετε({ μήνυμα: "Μη έγκυρα διαπιστευτήρια σύνδεσης" });
    }

    συνθ ωφέλιμο φορτίο = { ταυτότητα χρήστη: ταυτότητα χρήστη };
    συνθ token = generateToken (ωφέλιμο φορτίο);
    res.cookie('ένδειξη', διακριτικό, { http Μόνο: αληθής });
    res.status(200).json({ μήνυμα: 'Επιτυχής σύνδεση'});
    } σύλληψη (λάθος) {
    κονσόλα.log (σφάλμα);
    res.status(500).στείλετε({ μήνυμα: "Παρουσιάστηκε σφάλμα κατά τη σύνδεση" });
    }
    };

    Όταν ένας χρήστης στέλνει ένα αίτημα στο /login διαδρομή, θα πρέπει να περάσουν τα διαπιστευτήρια ελέγχου ταυτότητας στο σώμα αιτήματος. Στη συνέχεια, ο κώδικας επαληθεύει αυτά τα διαπιστευτήρια και δημιουργεί ένα JSON Web Token. Το διακριτικό αποθηκεύεται με ασφάλεια σε ένα cookie με το http Μόνο η σημαία ορίστηκε σε true. Αυτό αποτρέπει την πρόσβαση της JavaScript από την πλευρά του πελάτη στο διακριτικό, προστατεύοντας από πιθανές επιθέσεις δέσμης ενεργειών μεταξύ τοποθεσιών (XSS).
  3. Τέλος, ορίστε μια προστατευμένη διαδρομή:
    exports.getUsers = ασυγχρονισμός (απαιτ., ανταπ.) => {
    δοκιμάστε {
    συνθ χρήστες = αναμένω User.find({});
    res.json (χρήστες);
    } σύλληψη (λάθος) {
    κονσόλα.log (σφάλμα);
    res.status(500).στείλετε({ μήνυμα: 'Παρουσιάστηκε σφάλμα!!' });
    }
    };
    Με την αποθήκευση του JWT σε ένα cookie, τα επόμενα αιτήματα API από τον πιστοποιημένο χρήστη θα περιλαμβάνουν αυτόματα το διακριτικό, επιτρέποντας στον διακομιστή να επικυρώσει και να εξουσιοδοτήσει τα αιτήματα.

Δημιουργήστε ένα ενδιάμεσο λογισμικό ελέγχου ταυτότητας

Τώρα που έχετε ορίσει έναν ελεγκτή σύνδεσης που δημιουργεί ένα διακριτικό JWT μετά τον επιτυχή έλεγχο ταυτότητας, ορίστε συναρτήσεις ελέγχου ταυτότητας ενδιάμεσου λογισμικού που θα δημιουργήσουν και θα επαληθεύσουν το διακριτικό JWT.

Στον ριζικό κατάλογο, δημιουργήστε έναν νέο φάκελο, ενδιάμεσο λογισμικό. Μέσα σε αυτόν τον φάκελο, προσθέστε δύο αρχεία: auth.js και config.js.

Προσθέστε αυτόν τον κωδικό σε config.js:

συνθ κρυπτό = απαιτώ('κρυπτο');

μονάδα μέτρησης.εξαγωγές = {
SecretKey: crypto.randomBytes(32).toString('γοητεύω')
};

Αυτός ο κώδικας δημιουργεί ένα νέο τυχαίο μυστικό κλειδί κάθε φορά που εκτελείται. Στη συνέχεια, μπορείτε να χρησιμοποιήσετε αυτό το μυστικό κλειδί για να υπογράψετε και να επαληθεύσετε την αυθεντικότητα των JWT. Μόλις ένας χρήστης πιστοποιηθεί με επιτυχία, δημιουργήστε και υπογράψτε ένα JWT με το μυστικό κλειδί. Στη συνέχεια, ο διακομιστής θα χρησιμοποιήσει το κλειδί για να επαληθεύσει ότι το JWT είναι έγκυρο.

Προσθέστε τον παρακάτω κώδικα auth.js που ορίζει λειτουργίες ενδιάμεσου λογισμικού που δημιουργούν και επαληθεύουν τα JWT.

συνθ jwt = απαιτώ('jsonwebtoken');
συνθ { secretKey } = απαιτώ('./config');

συνθ generateToken = (φορτίο επί πληρωμή) => {
συνθ token = jwt.sign (ωφέλιμο φορτίο, secretKey, { λήγει σε: '1 ώρα' });
ΕΠΙΣΤΡΟΦΗ διακριτικό ;
};

συνθ verifyToken = (req, res, επόμενο) => {
συνθ token = req.cookies.token;

αν (!token) {
ΕΠΙΣΤΡΟΦΗ res.status(401).json({ μήνυμα: "Δεν παρέχεται διακριτικό" });
}

jwt.verify (token, secretKey, (err, decoded) => {
αν (λάθος) {
ΕΠΙΣΤΡΟΦΗ res.status(401).json({ μήνυμα: 'Μη έγκυρο διακριτικό' });
}

req.userId = decoded.userId;
Επόμενο();
});
};

μονάδα μέτρησης.exports = {genereToken, verifyToken };

ο generateToken η λειτουργία δημιουργεί ένα JWT υπογράφοντας ένα ωφέλιμο φορτίο χρησιμοποιώντας ένα μυστικό κλειδί και ορίζοντας ένα χρόνο λήξης ενώ το verifyToken Η λειτουργία χρησιμεύει ως ενδιάμεσο λογισμικό για την επαλήθευση της αυθεντικότητας και της εγκυρότητας ενός παρεχόμενου διακριτικού.

Καθορίστε τις διαδρομές API

Δημιούργησε ένα νέο routes/userRoutes.js αρχείο στον ριζικό κατάλογο και προσθέστε τον ακόλουθο κώδικα.

συνθ εκφράζω = απαιτώ('εξπρές');
συνθ δρομολογητής = εξπρές. Router();
συνθ userControllers = απαιτώ("../controllers/userControllers");
συνθ { verifyToken } = απαιτώ("../middleware/auth");
router.post('/api/register', userControllers.registerUser);
router.post('/api/login', userControllers.loginUser);
router.get('/api/χρήστες', verifyToken, userControllers.getUsers);
μονάδα μέτρησης.exports = δρομολογητής;

Ενημερώστε το σημείο εισόδου του διακομιστή σας

Ενημερώστε το server.js αρχείο με τον παρακάτω κώδικα.

συνθ εκφράζω = απαιτώ('εξπρές');
συνθ κορς = απαιτώ('κορς');
συνθ app = express();
συνθ λιμάνι = 5000;
απαιτώ('dotenv').config();
συνθ connectDB = απαιτώ("./utils/db");
συνθ cookieParser = απαιτώ("cookie-parser");

connectDB();

app.use (express.json());
app.use (express.urlencoded({ επεκτάθηκε: αληθής }));
app.use (cors());
app.use (cookieParser());
συνθ userRoutes = απαιτώ("./routes/userRoutes");
app.use('/', userRoutes);

app.listen (port, () => {
κονσόλα.κούτσουρο(`Ο διακομιστής ακούει στο http://localhost:${port}`);
});

Για να δοκιμάσετε το REST API, περιστρέψτε τον διακομιστή ανάπτυξης και κάντε αιτήματα API στα καθορισμένα τελικά σημεία:

διακομιστής κόμβου.js

Ασφάλεια Node.js REST API

Η ασφάλεια των Node.js REST API υπερβαίνει τη χρήση απλώς JWT, αν και διαδραματίζουν κρίσιμο ρόλο στον έλεγχο ταυτότητας και εξουσιοδότηση, είναι απαραίτητο να υιοθετήσετε μια ολιστική προσέγγιση ασφάλειας για την ασφάλεια για την προστασία του backend σας συστήματα. Παράλληλα με τα JWT, θα πρέπει επίσης να εξετάσετε το ενδεχόμενο εφαρμογής HTTPS για την κρυπτογράφηση της επικοινωνίας, την επικύρωση εισόδου και την απολύμανση και πολλά άλλα.

Συνδυάζοντας πολλαπλά μέτρα ασφαλείας, μπορείτε να δημιουργήσετε ένα ισχυρό πλαίσιο ασφαλείας για εσάς Node.js REST API και ελαχιστοποιήστε τον κίνδυνο μη εξουσιοδοτημένης πρόσβασης, παραβιάσεων δεδομένων και άλλης ασφάλειας απειλές.