Ένα τυπικό έργο Next.js ακολουθεί μια συγκεκριμένη δομή αρχείων και καταλόγων που διευκολύνει τις δυνατότητές του όπως η δρομολόγηση, τα API endpoints και η διαχείριση στατικών πόρων. Ακολουθεί μια τυπική διάταξη:
public/: Φιλοξενεί στατικά στοιχεία όπως εικόνες, γραμματοσειρές και άλλα αρχεία. Τα αρχεία εδώ είναι προσβάσιμα στη ριζική διαδρομή (/).
app/: Κεντρικός φάκελος για τις σελίδες, τα layouts, τα components και τις διαδρομές API της εφαρμογής σας. Υιοθετεί την παραδοχή App Router, επιτρέποντας προηγμένα χαρακτηριστικά δρομολόγησης και διαχωρισμό components server-client.
app/layout.tsx: Ορίζει το ριζικό layout για την εφαρμογή σας, περιβάλλοντας όλες τις σελίδες και παρέχοντας συνεπή στοιχεία UI όπως κεφαλίδες, υποσέλιδα και γραμμές πλοήγησης.
app/page.tsx: Λειτουργεί ως σημείο εισόδου για τη ριζική διαδρομή /, αποδίδοντας την αρχική σελίδα.
app/[route]/page.tsx: Διαχειρίζεται στατικές και δυναμικές διαδρομές. Κάθε φάκελος εντός του app/ αντιπροσωπεύει ένα τμήμα διαδρομής, και το page.tsx εντός αυτών των φακέλων αντιστοιχεί στο component της διαδρομής.
app/api/: Περιέχει διαδρομές API, επιτρέποντάς σας να δημιουργείτε serverless functions που διαχειρίζονται HTTP αιτήματα. Αυτές οι διαδρομές αντικαθιστούν τον παραδοσιακό φάκελο pages/api.
app/components/: Φιλοξενεί επαναχρησιμοποιήσιμα React components που μπορούν να χρησιμοποιηθούν σε διαφορετικές σελίδες και layouts.
app/styles/: Περιέχει παγκόσμια CSS αρχεία και CSS Modules για στυλ περιορισμένου πεδίου σε components.
app/utils/: Περιλαμβάνει βοηθητικές συναρτήσεις, βοηθητικά modules και άλλη λογική που δεν σχετίζεται με το UI και μπορεί να μοιραστεί σε όλη την εφαρμογή.
.env.local: Αποθηκεύει μεταβλητές περιβάλλοντος που είναι συγκεκριμένες για το τοπικό περιβάλλον ανάπτυξης. Αυτές οι μεταβλητές δεν δεσμεύονται για έλεγχο έκδοσης.
next.config.js: Προσαρμόζει τη συμπεριφορά του Next.js, συμπεριλαμβανομένων των ρυθμίσεων webpack, μεταβλητών περιβάλλοντος και ρυθμίσεων ασφαλείας.
tsconfig.json: Ρυθμίζει τις ρυθμίσεις TypeScript για το έργο, επιτρέποντας τον έλεγχο τύπων και άλλα χαρακτηριστικά TypeScript.
package.json: Διαχειρίζεται τις εξαρτήσεις του έργου, τα scripts και τα μεταδεδομένα.
README.md: Παρέχει τεκμηρίωση και πληροφορίες σχετικά με το έργο, συμπεριλαμβανομένων οδηγιών ρύθμισης, κατευθυντήριων γραμμών χρήσης και άλλων σχετικών λεπτομερειών.
yarn.lock / package-lock.json: Κλειδώνει τις εξαρτήσεις του έργου σε συγκεκριμένες εκδόσεις, διασφαλίζοντας συνεπείς εγκαταστάσεις σε διαφορετικά περιβάλλοντα.
Client-Side in Next.js
File-Based Routing in the app Directory
Ο φάκελος app είναι η βάση της δρομολόγησης στις τελευταίες εκδόσεις του Next.js. Εκμεταλλεύεται το σύστημα αρχείων για να ορίσει διαδρομές, καθιστώντας τη διαχείριση διαδρομών διαισθητική και κλιμακούμενη.
app/page.tsx: Διαχειρίζεται τα αιτήματα στη ρίζα διαδρομή /.
app/layout.tsx: Ορίζει τη διάταξη για την εφαρμογή, περιβάλλοντας όλες τις σελίδες.
Υλοποίηση:
tsxCopy code// app/page.tsxexportdefaultfunctionHomePage() {return (<div><h1>Welcome to the Home Page!</h1><p>This is the root route.</p></div>);}
Εξήγηση:
Ορισμός Διαδρομής: Το αρχείο page.tsx ακριβώς κάτω από τον φάκελο app αντιστοιχεί στη διαδρομή /.
Απόδοση: Αυτό το συστατικό αποδίδει το περιεχόμενο για την αρχική σελίδα.
Ενσωμάτωση Διάταξης: Το συστατικό HomePage περιβάλλεται από το layout.tsx, το οποίο μπορεί να περιλαμβάνει κεφαλίδες, υποσέλιδα και άλλα κοινά στοιχεία.
// app/about/page.tsxexportdefaultfunctionAboutPage() {return (<div><h1>About Us</h1><p>Learn more about our mission and values.</p></div>);}
Εξήγηση:
Ορισμός Διαδρομής: Το αρχείο page.tsx μέσα στον φάκελο about αντιστοιχεί στη διαδρομή /about.
Απόδοση: Αυτό το συστατικό αποδίδει το περιεχόμενο για τη σελίδα σχετικά με.
Δυναμικές Διαδρομές
Οι δυναμικές διαδρομές επιτρέπουν την επεξεργασία διαδρομών με μεταβλητά τμήματα, επιτρέποντας στις εφαρμογές να εμφανίζουν περιεχόμενο με βάση παραμέτρους όπως IDs, slugs, κ.λπ.
tsxCopy code// app/posts/[id]/page.tsximport { useRouter } from'next/navigation';interfacePostProps {params: { id:string };}exportdefaultfunctionPostPage({ params }:PostProps) {const { id } = params;// Fetch post data based on 'id'return (<div><h1>Post #{id}</h1><p>This is the content of post {id}.</p></div>);}
Εξήγηση:
Δυναμικό Τμήμα:[id] δηλώνει ένα δυναμικό τμήμα στη διαδρομή, καταγράφοντας την παράμετρο id από το URL.
Πρόσβαση σε Παραμέτρους: Το αντικείμενο params περιέχει τις δυναμικές παραμέτρους, προσβάσιμες μέσα στο συστατικό.
Ταίριασμα Διαδρομών: Οποιαδήποτε διαδρομή ταιριάζει με το /posts/*, όπως /posts/1, /posts/abc, κ.λπ., θα διαχειρίζεται από αυτό το συστατικό.
Εγκατεστημένες Διαδρομές
Το Next.js υποστηρίζει εγκατεστημένες διαδρομές, επιτρέποντας ιεραρχικές δομές διαδρομών που αντικατοπτρίζουν τη διάταξη του καταλόγου.
tsxCopy code// app/dashboard/settings/profile/page.tsxexportdefaultfunctionProfileSettingsPage() {return (<div><h1>Profile Settings</h1><p>Manage your profile information here.</p></div>);}
Εξήγηση:
Βαθιά Εγκατάσταση: Το αρχείο page.tsx μέσα στο dashboard/settings/profile/ αντιστοιχεί στη διαδρομή /dashboard/settings/profile.
Αντανάκλαση Ιεραρχίας: Η δομή του καταλόγου αντανακλά τη διαδρομή URL, ενισχύοντας τη συντηρησιμότητα και την καθαρότητα.
Διαδρομές Catch-All
Οι διαδρομές catch-all χειρίζονται πολλαπλά εσωτερικά τμήματα ή άγνωστες διαδρομές, παρέχοντας ευελιξία στη διαχείριση διαδρομών.
// app/[...slug]/page.tsxinterfaceCatchAllProps {params: { slug:string[] };}exportdefaultfunctionCatchAllPage({ params }:CatchAllProps) {const { slug } = params;constfullPath=`/${slug.join('/')}`;return (<div><h1>Catch-All Route</h1><p>You have navigated to: {fullPath}</p></div>);}
Εξήγηση:
Catch-All Segment:[...slug] καταγράφει όλα τα υπόλοιπα τμήματα διαδρομής ως πίνακα.
Χρήση: Χρήσιμο για την αντιμετώπιση δυναμικών σεναρίων δρομολόγησης όπως διαδρομές που δημιουργούνται από χρήστες, φωλιασμένες κατηγορίες κ.λπ.
Ταυτοποίηση Διαδρομής: Διαδρομές όπως /anything/here, /foo/bar/baz, κ.λπ., διαχειρίζονται από αυτό το συστατικό.
Πιθανές Ευπάθειες Πελάτη
Ενώ το Next.js παρέχει μια ασφαλή βάση, οι ακατάλληλες πρακτικές κωδικοποίησης μπορούν να εισάγουν ευπάθειες. Κύριες ευπάθειες πελάτη περιλαμβάνουν:
Cross-Site Scripting (XSS)
Οι επιθέσεις XSS συμβαίνουν όταν κακόβουλα σενάρια εισάγονται σε αξιόπιστους ιστότοπους. Οι επιτιθέμενοι μπορούν να εκτελούν σενάρια στους περιηγητές των χρηστών, κλέβοντας δεδομένα ή εκτελώντας ενέργειες εκ μέρους του χρήστη.
Παράδειγμα Ευάλωτου Κώδικα:
// Dangerous: Injecting user input directly into HTMLfunctionComment({ userInput }) {return <divdangerouslySetInnerHTML={{ __html: userInput }} />;}
Γιατί Είναι Ευάλωτο: Η χρήση του dangerouslySetInnerHTML με μη αξιόπιστα δεδομένα επιτρέπει στους επιτιθέμενους να εισάγουν κακόβουλα σενάρια.
Εισαγωγή Προτύπων από την Πελάτη
Συμβαίνει όταν οι είσοδοι χρηστών δεν διαχειρίζονται σωστά στα πρότυπα, επιτρέποντας στους επιτιθέμενους να εισάγουν και να εκτελούν πρότυπα ή εκφράσεις.
Παράδειγμα Ευάλωτου Κώδικα:
import React from'react';import ejs from'ejs';functionRenderTemplate({ template, data }) {consthtml=ejs.render(template, data);return <divdangerouslySetInnerHTML={{ __html: html }} />;}
Γιατί είναι ευάλωτο: Εάν το template ή το data περιλαμβάνει κακόβουλο περιεχόμενο, μπορεί να οδηγήσει σε εκτέλεση μη προγραμματισμένου κώδικα.
Διαδρομή Πελάτη Traversal
Είναι μια ευπάθεια που επιτρέπει στους επιτιθέμενους να χειρίζονται τις διαδρομές πλευράς πελάτη για να εκτελούν μη προγραμματισμένες ενέργειες, όπως η Cross-Site Request Forgery (CSRF). Σε αντίθεση με τη διαδρομή traversal πλευράς διακομιστή, η οποία στοχεύει στο σύστημα αρχείων του διακομιστή, η CSPT επικεντρώνεται στην εκμετάλλευση μηχανισμών πλευράς πελάτη για να ανακατευθύνει νόμιμα API αιτήματα σε κακόβουλους προορισμούς.
Παράδειγμα Ευάλωτου Κώδικα:
Μια εφαρμογή Next.js επιτρέπει στους χρήστες να ανεβάζουν και να κατεβάζουν αρχεία. Η δυνατότητα λήψης υλοποιείται στην πλευρά του πελάτη, όπου οι χρήστες μπορούν να καθορίσουν τη διαδρομή του αρχείου για λήψη.
Στόχος του Επιτιθέμενου: Να εκτελέσει μια επίθεση CSRF για να διαγράψει ένα κρίσιμο αρχείο (π.χ., admin/config.json) χειραγωγώντας το filePath.
Εκμετάλλευση CSPT:
Κακόβουλη Είσοδος: Ο επιτιθέμενος δημιουργεί μια διεύθυνση URL με χειραγωγημένο filePath όπως ../deleteFile/config.json.
Κλήση API που Απορρέει: Ο κωδικός της πλευράς του πελάτη κάνει ένα αίτημα προς /api/files/../deleteFile/config.json.
Διαχείριση από τον Διακομιστή: Εάν ο διακομιστής δεν επικυρώνει το filePath, επεξεργάζεται το αίτημα, ενδεχομένως διαγράφοντας ή εκθέτοντας ευαίσθητα αρχεία.
Εκτέλεση CSRF:
Δημιουργημένος Σύνδεσμος: Ο επιτιθέμενος στέλνει στο θύμα έναν σύνδεσμο ή ενσωματώνει ένα κακόβουλο σενάριο που ενεργοποιεί το αίτημα λήψης με το χειραγωγημένο filePath.
Αποτέλεσμα: Το θύμα εκτελεί άθελά του την ενέργεια, οδηγώντας σε μη εξουσιοδοτημένη πρόσβαση ή διαγραφή αρχείων.
Γιατί Είναι Ευάλωτο
Έλλειψη Επικύρωσης Εισόδου: Η πλευρά του πελάτη επιτρέπει αυθαίρετες εισόδους filePath, διευκολύνοντας την περιήγηση διαδρομών.
Εμπιστοσύνη στις Εισόδους του Πελάτη: Η API πλευρά του διακομιστή εμπιστεύεται και επεξεργάζεται το filePath χωρίς απολύμανση.
Πιθανές Ενέργειες API: Εάν το API endpoint εκτελεί ενέργειες που αλλάζουν την κατάσταση (π.χ., διαγραφή, τροποποίηση αρχείων), μπορεί να εκμεταλλευτεί μέσω CSPT.
Server-Side στο Next.js
Server-Side Rendering (SSR)
Οι σελίδες αποδίδονται στον διακομιστή σε κάθε αίτημα, διασφαλίζοντας ότι ο χρήστης λαμβάνει πλήρως αποδοσμένο HTML. Σε αυτή την περίπτωση θα πρέπει να δημιουργήσετε τον δικό σας προσαρμοσμένο διακομιστή για να επεξεργαστείτε τα αιτήματα.
Χρήσεις:
Δυναμικό περιεχόμενο που αλλάζει συχνά.
Βελτιστοποίηση SEO, καθώς οι μηχανές αναζήτησης μπορούν να ανιχνεύσουν τη πλήρως αποδοσμένη σελίδα.
Υλοποίηση:
// pages/index.jsexportasyncfunctiongetServerSideProps(context) {constres=awaitfetch('https://api.example.com/data');constdata=awaitres.json();return { props: { data } };}functionHomePage({ data }) {return <div>{data.title}</div>;}exportdefault HomePage;
Static Site Generation (SSG)
Οι σελίδες προ-δημιουργούνται κατά τη διάρκεια της διαδικασίας κατασκευής, με αποτέλεσμα ταχύτερους χρόνους φόρτωσης και μειωμένο φορτίο στον διακομιστή.
Use Cases:
Περιεχόμενο που δεν αλλάζει συχνά.
Ιστολόγια, τεκμηρίωση, σελίδες μάρκετινγκ.
Implementation:
// pages/index.jsexportasyncfunctiongetStaticProps() {constres=awaitfetch('https://api.example.com/data');constdata=awaitres.json();return { props: { data }, revalidate:60 }; // Revalidate every 60 seconds}functionHomePage({ data }) {return <div>{data.title}</div>;}exportdefault HomePage;
Serverless Functions (API Routes)
Το Next.js επιτρέπει τη δημιουργία API endpoints ως serverless functions. Αυτές οι λειτουργίες εκτελούνται κατόπιν αιτήματος χωρίς την ανάγκη για έναν αφιερωμένο διακομιστή.
Use Cases:
Διαχείριση υποβολών φορμών.
Αλληλεπίδραση με βάσεις δεδομένων.
Επεξεργασία δεδομένων ή ενσωμάτωση με τρίτες APIs.
Implementation:
Με την εισαγωγή του καταλόγου app στο Next.js 13, η δρομολόγηση και η διαχείριση API έχουν γίνει πιο ευέλικτες και ισχυρές. Αυτή η σύγχρονη προσέγγιση ευθυγραμμίζεται στενά με το σύστημα δρομολόγησης βασισμένο σε αρχεία αλλά εισάγει ενισχυμένες δυνατότητες, συμπεριλαμβανομένης της υποστήριξης για server και client components.
// app/api/hello/route.jsexportasyncfunctionPOST(request) {returnnewResponse(JSON.stringify({ message:'Hello from App Router!' }), {status:200,headers: { 'Content-Type':'application/json' },});}// Client-side fetch to access the API endpointfetch('/api/submit', {method:'POST',headers: { 'Content-Type':'application/json' },body:JSON.stringify({ name:'John Doe' }),}).then((res) =>res.json()).then((data) =>console.log(data));
Εξήγηση:
Τοποθεσία: Οι διαδρομές API τοποθετούνται στον φάκελο app/api/.
Ονομασία Αρχείων: Κάθε τελικό σημείο API βρίσκεται στον δικό του φάκελο που περιέχει ένα αρχείο route.js ή route.ts.
Εξαγόμενες Συναρτήσεις: Αντί για μία μόνο προεπιλεγμένη εξαγωγή, εξάγονται συγκεκριμένες συναρτήσεις HTTP μεθόδων (π.χ., GET, POST).
Διαχείριση Απαντήσεων: Χρησιμοποιήστε τον κατασκευαστή Response για να επιστρέψετε απαντήσεις, επιτρέποντας περισσότερη έλεγχο πάνω σε κεφαλίδες και κωδικούς κατάστασης.
Πώς να διαχειριστείτε άλλες διαδρομές και μεθόδους:
Διαχείριση Συγκεκριμένων Μεθόδων HTTP
Next.js 13+ σας επιτρέπει να ορίσετε χειριστές για συγκεκριμένες μεθόδους HTTP μέσα στο ίδιο αρχείο route.js ή route.ts, προάγοντας πιο καθαρό και οργανωμένο κώδικα.
Παράδειγμα:
// app/api/users/[id]/route.jsexportasyncfunctionGET(request, { params }) {const { id } = params;// Fetch user data based on 'id'returnnewResponse(JSON.stringify({ userId: id, name:'Jane Doe' }), {status:200,headers: { 'Content-Type':'application/json' },});}exportasyncfunctionPUT(request, { params }) {const { id } = params;// Update user data based on 'id'returnnewResponse(JSON.stringify({ message:`User ${id} updated.` }), {status:200,headers: { 'Content-Type':'application/json' },});}exportasyncfunctionDELETE(request, { params }) {const { id } = params;// Delete user based on 'id'returnnewResponse(JSON.stringify({ message:`User ${id} deleted.` }), {status:200,headers: { 'Content-Type':'application/json' },});}
Εξήγηση:
Πολλαπλές Εξαγωγές: Κάθε μέθοδος HTTP (GET, PUT, DELETE) έχει τη δική της εξαγόμενη συνάρτηση.
Παράμετροι: Το δεύτερο επιχείρημα παρέχει πρόσβαση σε παραμέτρους διαδρομής μέσω params.
Ενισχυμένες Απαντήσεις: Μεγαλύτερος έλεγχος πάνω στα αντικείμενα απάντησης, επιτρέποντας ακριβή διαχείριση κεφαλίδων και κωδικών κατάστασης.
Catch-All και Ενσωματωμένες Διαδρομές
Το Next.js 13+ υποστηρίζει προηγμένα χαρακτηριστικά δρομολόγησης όπως διαδρομές catch-all και ενσωματωμένες API διαδρομές, επιτρέποντας πιο δυναμικές και κλιμακούμενες δομές API.
Σύνταξη:[...] δηλώνει ένα catch-all τμήμα, καταγράφοντας όλα τα εσωτερικά μονοπάτια.
Χρήση: Χρήσιμο για APIs που χρειάζονται να διαχειρίζονται διάφορα βάθη διαδρομών ή δυναμικά τμήματα.
Παράδειγμα Εσωτερικών Διαδρομών:
// app/api/posts/[postId]/comments/[commentId]/route.jsexportasyncfunctionGET(request, { params }) {const { postId,commentId } = params;// Fetch specific comment for a postreturnnewResponse(JSON.stringify({ postId, commentId, comment:'Great post!' }), {status:200,headers: { 'Content-Type':'application/json' },});}
Εξήγηση:
Βαθιά Εγκατάσταση: Επιτρέπει ιεραρχικές δομές API, αντικατοπτρίζοντας τις σχέσεις πόρων.
Πρόσβαση Παραμέτρων: Εύκολη πρόσβαση σε πολλαπλές παραμέτρους διαδρομής μέσω του αντικειμένου params.
Διαχείριση Διαδρομών API στο Next.js 12 και νωρίτερα
Διαδρομές API στον Κατάλογο pages (Next.js 12 και νωρίτερα)
Πριν το Next.js 13 εισαγάγει τον κατάλογο app και βελτιώσει τις δυνατότητες δρομολόγησης, οι διαδρομές API ορίζονταν κυρίως εντός του καταλόγου pages. Αυτή η προσέγγιση εξακολουθεί να χρησιμοποιείται ευρέως και υποστηρίζεται στο Next.js 12 και σε παλαιότερες εκδόσεις.
javascriptCopy code// pages/api/users/[id].jsexportdefaultfunctionhandler(req, res) {const {query: { id },method,} = req;switch (method) {case'GET':// Fetch user data based on 'id'res.status(200).json({ userId: id, name:'John Doe' });break;case'PUT':// Update user data based on 'id'res.status(200).json({ message:`User ${id} updated.` });break;case'DELETE':// Delete user based on 'id'res.status(200).json({ message:`User ${id} deleted.` });break;default:res.setHeader('Allow', ['GET','PUT','DELETE']);res.status(405).end(`Method ${method} Not Allowed`);}}
Εξήγηση:
Δυναμικά Τμήματα: Τα τετράγωνα αγκύλες ([id].js) δηλώνουν δυναμικά τμήματα διαδρομής.
Πρόσβαση σε Παραμέτρους: Χρησιμοποιήστε req.query.id για να αποκτήσετε πρόσβαση στην δυναμική παράμετρο.
Διαχείριση Μεθόδων: Χρησιμοποιήστε λογική συνθήκης για να διαχειριστείτε διαφορετικές μεθόδους HTTP (GET, PUT, DELETE, κ.λπ.).
Διαχείριση Διαφορετικών Μεθόδων HTTP
Ενώ το βασικό παράδειγμα διαδρομής API διαχειρίζεται όλες τις μεθόδους HTTP μέσα σε μία μόνο συνάρτηση, μπορείτε να δομήσετε τον κώδικά σας για να διαχειριστείτε κάθε μέθοδο ρητά για καλύτερη σαφήνεια και συντηρησιμότητα.
Παράδειγμα:
javascriptCopy code// pages/api/posts.jsexportdefaultasyncfunctionhandler(req, res) {const { method } = req;switch (method) {case'GET':// Handle GET requestres.status(200).json({ message:'Fetching posts.' });break;case'POST':// Handle POST requestres.status(201).json({ message:'Post created.' });break;default:res.setHeader('Allow', ['GET','POST']);res.status(405).end(`Method ${method} Not Allowed`);}}
Καλύτερες Πρακτικές:
Διαχωρισμός Ανησυχιών: Ξεκάθαρα διαχωρίστε τη λογική για διαφορετικές μεθόδους HTTP.
Συνοχή Απόκρισης: Διασφαλίστε συνεπείς δομές απόκρισης για ευκολία χειρισμού από την πλευρά του πελάτη.
Διαχείριση Σφαλμάτων: Χειριστείτε με κομψότητα μη υποστηριζόμενες μεθόδους και απρόσμενα σφάλματα.
Ρύθμιση CORS
Ελέγξτε ποιες προελεύσεις μπορούν να έχουν πρόσβαση στις διαδρομές API σας, μετριάζοντας τις ευπάθειες Cross-Origin Resource Sharing (CORS).
Κακό Παράδειγμα Ρύθμισης:
// app/api/data/route.jsexportasyncfunctionGET(request) {returnnewResponse(JSON.stringify({ data:'Public Data' }), {status:200,headers: {'Access-Control-Allow-Origin':'*',// Allows any origin'Access-Control-Allow-Methods':'GET, POST, PUT, DELETE',},});}
Σημειώστε ότι το CORS μπορεί επίσης να ρυθμιστεί σε όλες τις διαδρομές API μέσα στο middleware.ts αρχείο:
// app/middleware.tsimport { NextResponse } from'next/server';importtype { NextRequest } from'next/server';exportfunctionmiddleware(request:NextRequest) {constallowedOrigins= ['https://yourdomain.com','https://sub.yourdomain.com'];constorigin=request.headers.get('Origin');constresponse=NextResponse.next();if (allowedOrigins.includes(origin ||'')) {response.headers.set('Access-Control-Allow-Origin', origin ||'');response.headers.set('Access-Control-Allow-Methods','GET, POST, PUT, DELETE, OPTIONS');response.headers.set('Access-Control-Allow-Headers','Content-Type, Authorization');// If credentials are needed:// response.headers.set('Access-Control-Allow-Credentials', 'true');}// Handle preflight requestsif (request.method ==='OPTIONS') {returnnewResponse(null, {status:204,headers:response.headers,});}return response;}exportconstconfig= {matcher:'/api/:path*',// Apply to all API routes};
Πρόβλημα:
Access-Control-Allow-Origin: '*': Επιτρέπει σε οποιαδήποτε ιστοσελίδα να έχει πρόσβαση στο API, ενδεχομένως επιτρέποντας σε κακόβουλες ιστοσελίδες να αλληλεπιδρούν με το API σας χωρίς περιορισμούς.
Ευρεία Επιτρεπόμενη Μέθοδος: Η επιτρεπόμενη χρήση όλων των μεθόδων μπορεί να επιτρέψει στους επιτιθέμενους να εκτελούν ανεπιθύμητες ενέργειες.
Πώς οι επιτιθέμενοι το εκμεταλλεύονται:
Οι επιτιθέμενοι μπορούν να δημιουργήσουν κακόβουλες ιστοσελίδες που κάνουν αιτήματα στο API σας, ενδεχομένως εκμεταλλευόμενοι λειτουργίες όπως η ανάκτηση δεδομένων, η επεξεργασία δεδομένων ή η ενεργοποίηση ανεπιθύμητων ενεργειών εκ μέρους των αυθεντικοποιημένων χρηστών.
Είναι εύκολο να χρησιμοποιηθεί ο κώδικας που χρησιμοποιείται από τον διακομιστή και στον κώδικα που εκτίθεται και χρησιμοποιείται από την πλευρά του πελάτη, ο καλύτερος τρόπος για να διασφαλίσετε ότι ένα αρχείο κώδικα δεν εκτίθεται ποτέ στην πλευρά του πελάτη είναι να χρησιμοποιήσετε αυτήν την εισαγωγή στην αρχή του αρχείου:
import"server-only";
Κύρια Αρχεία και οι Ρόλοι τους
middleware.ts / middleware.js
Τοποθεσία: Ρίζα του έργου ή εντός του src/.
Σκοπός: Εκτελεί κώδικα στη λειτουργία serverless του server πριν επεξεργαστεί ένα αίτημα, επιτρέποντας εργασίες όπως η αυθεντικοποίηση, οι ανακατευθύνσεις ή η τροποποίηση των απαντήσεων.
Ροή Εκτέλεσης:
Εισερχόμενο Αίτημα: Το middleware παρεμβαίνει στο αίτημα.
Επεξεργασία: Εκτελεί λειτουργίες με βάση το αίτημα (π.χ., έλεγχος αυθεντικοποίησης).
Τροποποίηση Απάντησης: Μπορεί να αλλάξει την απάντηση ή να περάσει τον έλεγχο στον επόμενο χειριστή.
Σκοπός: Ρυθμίζει τη συμπεριφορά του Next.js, ενεργοποιώντας ή απενεργοποιώντας δυνατότητες, προσαρμόζοντας τις ρυθμίσεις webpack, ορίζοντας μεταβλητές περιβάλλοντος και ρυθμίζοντας διάφορες δυνατότητες ασφαλείας.
Βασικές Ρυθμίσεις Ασφαλείας:
Ασφαλιστικές Κεφαλίδες
Οι ασφαλιστικές κεφαλίδες ενισχύουν την ασφάλεια της εφαρμογής σας, δίνοντας οδηγίες στους περιηγητές για το πώς να χειρίζονται το περιεχόμενο. Βοηθούν στη μείωση διαφόρων επιθέσεων όπως το Cross-Site Scripting (XSS), το Clickjacking και το MIME type sniffing:
Το Next.js βελτιστοποιεί τις εικόνες για απόδοση, αλλά οι κακές ρυθμίσεις μπορεί να οδηγήσουν σε ευπάθειες ασφαλείας, όπως η δυνατότητα μη αξιόπιστων πηγών να εισάγουν κακόβουλο περιεχόμενο.
Κακό Παράδειγμα Ρύθμισης:
// next.config.jsmodule.exports= {images: {domains: ['*'],// Allows images from any domain},};
Πρόβλημα:
'*': Επιτρέπει τη φόρτωση εικόνων από οποιαδήποτε εξωτερική πηγή, συμπεριλαμβανομένων μη αξιόπιστων ή κακόβουλων τομέων. Οι επιτιθέμενοι μπορούν να φιλοξενούν εικόνες που περιέχουν κακόβουλα payloads ή περιεχόμενο που παραπλανεί τους χρήστες.
Ένα άλλο πρόβλημα μπορεί να είναι η δυνατότητα να επιτρέπεται ένας τομέας όπου ο καθένας μπορεί να ανεβάσει μια εικόνα (όπως το raw.githubusercontent.com)
Πώς οι επιτιθέμενοι το εκμεταλλεύονται:
Με την εισαγωγή εικόνων από κακόβουλες πηγές, οι επιτιθέμενοι μπορούν να εκτελούν επιθέσεις phishing, να εμφανίζουν παραπλανητικές πληροφορίες ή να εκμεταλλεύονται ευπάθειες σε βιβλιοθήκες απόδοσης εικόνας.
Έκθεση Μεταβλητών Περιβάλλοντος
Διαχειριστείτε ευαίσθητες πληροφορίες όπως API keys και διαπιστευτήρια βάσης δεδομένων με ασφάλεια χωρίς να τις εκθέτετε στον πελάτη.
α. Έκθεση Ευαίσθητων Μεταβλητών
Κακό Παράδειγμα Διαμόρφωσης:
// next.config.jsmodule.exports= {env: {SECRET_API_KEY:process.env.SECRET_API_KEY,// Exposed to the clientNEXT_PUBLIC_API_URL:process.env.NEXT_PUBLIC_API_URL,// Correctly prefixed for client},};
Πρόβλημα:
SECRET_API_KEY: Χωρίς το πρόθεμα NEXT_PUBLIC_, το Next.js δεν εκθέτει μεταβλητές στον πελάτη. Ωστόσο, αν τυχαία προστεθεί το πρόθεμα (π.χ., NEXT_PUBLIC_SECRET_API_KEY), γίνεται προσβάσιμο από την πλευρά του πελάτη.
Πώς το εκμεταλλεύονται οι επιτιθέμενοι:
Αν ευαίσθητες μεταβλητές εκτεθούν στον πελάτη, οι επιτιθέμενοι μπορούν να τις ανακτήσουν ελέγχοντας τον κωδικό της πλευράς του πελάτη ή τα αιτήματα δικτύου, αποκτώντας μη εξουσιοδοτημένη πρόσβαση σε APIs, βάσεις δεδομένων ή άλλες υπηρεσίες.
Ανακατευθύνσεις
Διαχειριστείτε τις ανακατευθύνσεις και τις επαναγραφές URL μέσα στην εφαρμογή σας, διασφαλίζοντας ότι οι χρήστες κατευθύνονται κατάλληλα χωρίς να εισάγονται ευπάθειες ανοιχτής ανακατεύθυνσης.
α. Ευπάθεια Ανοιχτής Ανακατεύθυνσης
Κακό Παράδειγμα Διαμόρφωσης:
// next.config.jsmodule.exports= {asyncredirects() {return [{source:'/redirect',destination: (req) =>req.query.url,// Dynamically redirects based on query parameterpermanent:false,},];},};
Πρόβλημα:
Δυναμικός Προορισμός: Επιτρέπει στους χρήστες να καθορίζουν οποιαδήποτε διεύθυνση URL, διευκολύνοντας επιθέσεις ανοιχτής ανακατεύθυνσης.
Εμπιστοσύνη στην Είσοδο Χρήστη: Οι ανακατευθύνσεις σε διευθύνσεις URL που παρέχονται από τους χρήστες χωρίς έλεγχο μπορεί να οδηγήσουν σε phishing, διανομή κακόβουλου λογισμικού ή κλοπή διαπιστευτηρίων.
Πώς οι επιτιθέμενοι το εκμεταλλεύονται:
Οι επιτιθέμενοι μπορούν να δημιουργήσουν διευθύνσεις URL που φαίνεται να προέρχονται από το τομέα σας αλλά ανακατευθύνουν τους χρήστες σε κακόβουλες ιστοσελίδες. Για παράδειγμα:
Οι χρήστες που εμπιστεύονται το αρχικό domain μπορεί να πλοηγηθούν ακούσια σε επιβλαβείς ιστότοπους.
Ρύθμιση Webpack
Προσαρμόστε τις ρυθμίσεις Webpack για την εφαρμογή Next.js σας, οι οποίες μπορεί να εισάγουν ακούσια ευπάθειες ασφαλείας αν δεν διαχειριστούν προσεκτικά.
Έκθεση Ευαίσθητων Διαδρομών: Η αναγνώριση ευαίσθητων καταλόγων και η επιτρεπόμενη πρόσβαση από την πλευρά του πελάτη μπορεί να εκθέσει εμπιστευτικές πληροφορίες.
Συσκευασία Μυστικών: Εάν ευαίσθητα αρχεία είναι συσκευασμένα για τον πελάτη, το περιεχόμενό τους γίνεται προσβάσιμο μέσω χάρτη πηγής ή επιθεώρησης του κώδικα από την πλευρά του πελάτη.
Πώς οι επιτιθέμενοι το εκμεταλλεύονται:
Οι επιτιθέμενοι μπορούν να αποκτήσουν πρόσβαση ή να ανακατασκευάσουν τη δομή καταλόγων της εφαρμογής, ενδεχομένως βρίσκοντας και εκμεταλλευόμενοι ευαίσθητα αρχεία ή δεδομένα.
pages/_app.js και pages/_document.js
pages/_app.js
Σκοπός: Υπερκαλύπτει το προεπιλεγμένο συστατικό App, επιτρέποντας παγκόσμια κατάσταση, στυλ και συστατικά διάταξης.
Σκοπός: Ενώ το Next.js έρχεται με έναν ενσωματωμένο διακομιστή, μπορείτε να δημιουργήσετε έναν προσαρμοσμένο διακομιστή για προηγμένες περιπτώσεις χρήσης όπως προσαρμοσμένη δρομολόγηση ή ενσωμάτωση με υπάρχουσες υπηρεσίες backend.
Σημείωση: Η χρήση ενός προσαρμοσμένου διακομιστή μπορεί να περιορίσει τις επιλογές ανάπτυξης, ειδικά σε πλατφόρμες όπως η Vercel που βελτιστοποιούν για τον ενσωματωμένο διακομιστή του Next.js.
Σκοπός: Διαχείριση ευαίσθητων πληροφοριών και ρυθμίσεων εκτός του κώδικα.
Καλές Πρακτικές:
Χρησιμοποιήστε αρχεία .env: Αποθηκεύστε μεταβλητές όπως τα API keys σε .env.local (εξαιρούνται από τον έλεγχο έκδοσης).
Πρόσβαση σε Μεταβλητές με Ασφάλεια: Χρησιμοποιήστε process.env.VARIABLE_NAME για να αποκτήσετε πρόσβαση σε μεταβλητές περιβάλλοντος.
Ποτέ μην εκθέτετε μυστικά στον πελάτη: Διασφαλίστε ότι οι ευαίσθητες μεταβλητές χρησιμοποιούνται μόνο από την πλευρά του διακομιστή.
Παράδειγμα:
// next.config.jsmodule.exports= {env: {API_KEY:process.env.API_KEY,// Accessible on both client and serverSECRET_KEY:process.env.SECRET_KEY,// Be cautious if accessible on the client},};
Σημείωση: Για να περιορίσετε τις μεταβλητές μόνο στην πλευρά του διακομιστή, παραλείψτε τις από το αντικείμενο env ή προσθέστε το πρόθεμα NEXT_PUBLIC_ για έκθεση στον πελάτη.
Αυθεντικοποίηση και Εξουσιοδότηση
Προσέγγιση:
Αυθεντικοποίηση Βασισμένη σε Συνεδρίες: Χρησιμοποιήστε cookies για τη διαχείριση των συνεδριών χρηστών.
Αυθεντικοποίηση Βασισμένη σε Διακριτικά: Εφαρμόστε JWTs για αυθεντικοποίηση χωρίς κατάσταση.
Πάροχοι Τρίτων: Ενσωματώστε με παρόχους OAuth (π.χ., Google, GitHub) χρησιμοποιώντας βιβλιοθήκες όπως το next-auth.
Πρακτικές Ασφαλείας:
Ασφαλή Cookies: Ορίστε τα χαρακτηριστικά HttpOnly, Secure και SameSite.
Χάραξη Κωδικών Πρόσβασης: Πάντα να χαράσσετε τους κωδικούς πρόσβασης πριν τους αποθηκεύσετε.
Επικύρωση Εισόδου: Αποτρέψτε επιθέσεις εισαγωγής επικυρώνοντας και καθαρίζοντας τις εισόδους.