Praktisch webgebaseerd diep leren en beveiliging bij voorbeeld

Daisy's Profielfoto

Door Daisy

Praktisch webgebaseerd diep leren en beveiliging bij voorbeeld Derde editie Charlotte Harper 3 juli 2024 Bijgewerkt/geconverteerd op 3 juni 2025 Voorwoord: Beveiligingsoverwegingen in het bouwen van software voor internet zijn een belangrijk onderdeel van het plan en de uitvoering van elke webontwikkelaar, terwijl een prototype engineering van een prototype dat betrouwbaar, stabiel en nuttig is voor praktische doeleinden. De DOM (Document Object Markup), met de implementatie van HTML, JavaScript en CSS, evenals backend -software die Python, C/C ++, Java en Bash implementeert, geven webontwikkelaars de vrijheid en macht om een ​​breed scala van projecten te creëren, het gemiddelde gebruik van de gemiddelde, het gemiddelde van de gemiddelde, het gemiddelde gebruik van de gemiddelde, het gemiddelde van de gemiddelde als het gemiddelde van de gemiddelde gebruik te maken van de gemiddelde. Dood tijd of laat iets gedaan op internet, meestal op een touchscreen -smartphone -apparaat. De meeste mensen zouden niet eens weten waar ze moeten beginnen als ze een website helemaal opnieuw willen bouwen, ze zouden de neiging hebben om op de website van een ander te beginnen en iets te bouwen dat beperkt is in functionaliteit, betrouwbaarheid, gebruiksgemak en vooral creativiteit wanneer ze de nieuwste krachtige tools hadden die de limiet van het gebruik van gebruik en flexibiliteit in het gemak konden gebruiken, wat de limiet van het gemak in gebruik en flexibiliteit in het gemak zou hebben om te gebruiken. Als je een paar minuten de tijd hebt om dit boek te lezen en te leren wat ik je wil leren, of zelfs met mij persoonlijk over je doelen wil praten en wat begeleiding in de goede richting krijgt en gemotiveerd bent om te leren coderen en te schrijven van je eigen software, neem je dit boek mee naar huis en zet je wat tijd opzij om de volgende invloed, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige en belangrijke webtoepassing ook te maken en je wil en te schrijven, precies te nemen wat je wilt en de behoeften van je doelgroep opbouwt. Over mij: Ik ben een softwareontwikkelaar met een breed scala aan ervaring in C/C ++, Java, Python, HTML, CSS en JavaScript. Ik bouw websites die mensen willen gebruiken, willen bezoeken en zelfs verslaafd raken aan het gebruik alleen om tijd te leren, te herscheppen en te doden, en vooral, ik verkoop software. Als je een idee had om precies te hebben hoe je wilde dat een website eruit zou zien en functioneren, was je bereid me te ondersteunen, zodat ik aan mijn eigen behoeften kan voldoen terwijl ik de jouwe ontmoet, en je bent bereid om de kosten van het runnen van een website zelf te dekken, ik zou je de volgende YouTube, Tiktok, Twitter, Google, Google, Google of zelfs een high-tech beveiligings-app alleen u toegang hebben. In plaats van te proberen je mijn tijd te verkopen, probeer ik de jouwe te kopen: ik wil je er zelf over hebben om een ​​app (website) te bouwen met de informatie die al bestaat, en je te leren wat je nodig hebt om een ​​onafhankelijke softwareontwikkelaar, ondernemer te zijn, die een succesvolle carrière leidt op elk gewenste vakgebied. En laat me duidelijk zijn, de opleiding die ik je geef, zal informeel zijn. Je zou naar school kunnen gaan en dit allemaal leren met een formele opleiding, of dit boek zelfs op school lezen, je opdrachten voltooien en veel wegnemen van je opleiding, maar ik zal je niet formeel op de hot stoel zetten en je vragen om opdrachten te voltooien. Ik ben niet je professor, je kunt aan mij denken als een vriend die je wil begeleiden naar een carrière gedreven door je eigen persoonlijke succes. En ik verkoop je succes ook niet, je moet het met je tijd kopen. Leren te coderen heeft een steile leercurve en was nooit gemakkelijk, of zou zelfs moeten zijn. Je moet zo hard werken als je kunt en blijven proberen te falen en opnieuw te proberen, zelfs als je gefrustreerd bent om zelf apps te leren en te bouwen. Dat is in de aard van de code zelf. Code wordt uitgevoerd door een compiler die is ontworpen om de programmeerfoutmeldingen te geven, en deze zullen u leren hoe u moet coderen, zelfs als u de fout eenvoudigweg in uw zoekmachine kopieert en de voorbeelden van andere mensen leest. En ik moet zeggen dat je niet extreem rijk, slim, succesvol of zelfs gedetailleerd georiënteerd of georganiseerd hoeft te zijn om een ​​app te bouwen. De computer zorgt voor die organisatie voor u. Je hoeft alleen maar door de vallen en opstaan ​​te volharden, de focus te behouden en hard te werken aan wat je doet, en je zult een zeer succesvolle carrière hebben in het geheel van wat je doet. Wie ik ben: Ik realiseer me dat het laatste deel meer ging over leren en je neemt een manier uit dit boek. Wie ben ik precies? Dat is een ingewikkelde vraag. Ik ben daar zelf onduidelijk over, omdat ik last heb van medische aandoeningen die het voor mij moeilijk kunnen maken om dit boek soms te coderen of te schrijven, terwijl ik uitdagingen presenteert met socialisatie- en identiteitsproblemen die mijn leven moeilijker maken als het gaat om het introduceren van mezelf. Kortom, als je dit boek leest, bracht je het naar huis omdat je er doorheen draaide en dacht dat het nuttig was, of zelfs als je net zo ver erin leest, ben ik een gelijkgestemde persoon die je wil zien slagen in alles wat je doet. Ik ben eenEngineer mezelf, een softwareontwikkelaar en een student, en ik schrijf dit boek voor andere studenten die hun leven gemakkelijker willen maken door een handboek te hebben van de software die ze nodig hebben om hun leven gemakkelijker te maken door voorbeelden te geven die in elkaar passen als een grote puzzel in een werkende, nuttige, grote, functionele, samenhangende en boeiende app die succes kan stimuleren. Grotendeels, dit is wat ik doe: ik bouw apps om mezelf en andere mensen te helpen slagen. Ik ben ook een auteur, hoewel dit mijn eerste publicatie is die ik van plan ben te voltooien om mijn portfolio samen te stellen in een nuttig document, en ik ben ook een kunstenaar. Ik zal je dit toegeven, ik ben een soort vreemd persoon. Ik ben niet perfect, ik heb de wet gehad met de wet, zelfs ertoe leiden dat ik hogescholen en universiteiten verlaten en staten verlaten om te proberen een naam voor mezelf te maken met meer succes. Ik ben een vrouw van geboorte, ik draag make -up, maak foto's van mezelf, draag jurken en andere dameskleding en ik blijf me bewust van mezelf als een vrouw van nature. Ik heb in het verleden problemen gehad met andere mensen die hebben geleid tot worstelingen met het schrijven en bouwen van webapps, en ik bied mijn excuses aan dat ik dit boek niet eerder in handen heb kunnen krijgen: je had dit nodig. Je zult code willen lezen en schrijven die op mij lijkt en werkt als de mijne en hetzelfde doet, maar nog beter, want als je het je kunt veroorloven om dit boek te kopen in plaats van je toetsenbord te pureren zoals ik gewoon om een ​​boek te maken om er zelf geld voor te vragen, heb je de bronnen die je nodig hebt om succesvol te zijn in je leven. Ik had allerlei problemen met het opgroeien van familie, gezondheidstoestand, artsen, de media en de wet, en mijn code weerspiegelt diep de strijd die feminisme en vrouwelijke natuur is in een verdeelde en gefrustreerde wereld. Dit boek is echter iets waar ik diep om geef, mijn baby, mijn portfolio en mijn levensonderhoud, dus ik waardeer je overweging wanneer je de tekst naar huis neemt en er zorgvuldig overheen portrelt om van mij te leren. Houd er rekening mee dat ik niet perfect ben, dit boek zal fouten, revisies en nieuwe edities hebben, en je moet zo goed mogelijk met je logische brein denken om een ​​succesvolle ervaring met mijn schrijven te hebben. Begrijp ook dat ik goed voor je bedoel, zelfs als je voor uitdagingen wordt geconfronteerd tijdens het schrijven. Denk er zo over na: wanneer u gewoon een computersysteem kunt huren om alles te doen wat u zich kunt voorstellen in de digitale ruimte, alle informatie opslaat die u tegenkomt, analyseert en organiseren, en het komen begrijpen, zult u onvermijdelijk problemen ondervinden met de informatie die u inneemt en zelfs publiceert. Ik vertel je dit omdat ik dezelfde moeilijkheden tegenkom. Gebruik dit boek op eigen risico, werk samen met uw community en communities die voor u beschikbaar zijn om software te bouwen binnen een veilige setting, en neem dingen niet persoonlijk aan wanneer u faalt of zelfs op de verkeerde manier slaagt: zo ben ik zo ver gekomen, en waarom ik u deze tekst kan brengen en u kan slagen zonder de werking van de netwerk te doen. zal werken, internet. Je bent misschien niet erg bekend met wie ik ben met slechts een paar woorden, maar ik moedig je aan om verder te lezen, je zult me ​​leren kennen terwijl je me blijft lezen en begrijpen tijdens het bouwen van je eigen projecten om je werk te voltooien. Er zal geen huiswerk zijn met dit boek, zolang je professoren of leraren je niet toewijzen, maar ik moedig je ten zeerste aan om zelf een portfolio van projecten te bouwen terwijl je meegaat, evenals een Capstone -project dat laat zien hoe je kunt toepassen wat je hebt geleerd. Mijn Capstone -project is de basis voor het grootste deel van wat je in dit boek gaat lezen, omdat het code van mijn vorige projecten, code opneemt, die ik heb gemaakt en geleerd om methodisch met de hand te schrijven, en een breed scala aan ideeën en tips die me hebben geholpen om te slagen tot het punt waar ik een eenvoudige app kan spinnen die je volledig kan uitstrekken en lijkt en gedraagt ​​en gedraagt ​​een populaire app die je vriend of familie gebruikt, op het internet, op het internet, op het internet, of in het nieuws, of in het nieuws, of in het nieuws kunnen worden geactiveerd. Wat dit boek is: Dit boek is een tutorial bij voorbeeld. U kunt hier code vinden, instructies om te leren coderen, informatie over foutopsporingcode en fouten op het oplossen van stappen, instructies voor het oplossen van een back-up van en opslaan van uw code, opnieuw inzetten als iemand uw code doorbreekt, uw code beveiligt, uw code beveiligt, uw code implementeert, uw code build, uw app en uzelf Software die u opbouwt in het absoluut beste licht om de meest aantrekkelijke mogelijk te zijn voor uw eindgebruikers, de bezoekers van uw website. In dit boek zal ik een aantal voorbeelden van softwareontwerp demonstreren met een focus op internet als platform en beveiliging. We zullen het leren initiërenwoest
Praktisch webgebaseerd diep leren en beveiliging bij voorbeeld

Praktisch webgebaseerd diep leren en beveiliging bij voorbeeld Derde editie Charlotte Harper 3 juli 2024 Bijgewerkt/geconverteerd op 3 juni 2025

Voorwoord:

Beveiligingsoverwegingen in het bouwen van software voor internet zijn een belangrijk onderdeel van het plan en de uitvoering van elke webontwikkelaar, terwijl een prototype engineering van een prototype dat betrouwbaar, stabiel en nuttig is voor praktische doeleinden. De DOM (Document Object Markup), met de implementatie van HTML, JavaScript en CSS, evenals backend -software die Python, C/C ++, Java en Bash implementeert, geven webontwikkelaars de vrijheid en macht om een ​​breed scala van projecten te creëren, het gemiddelde gebruik van de gemiddelde, het gemiddelde van de gemiddelde, het gemiddelde gebruik van de gemiddelde, het gemiddelde van de gemiddelde als het gemiddelde van de gemiddelde gebruik te maken van de gemiddelde. Dood tijd of laat iets gedaan op internet, meestal op een touchscreen -smartphone -apparaat. De meeste mensen zouden niet eens weten waar ze moeten beginnen als ze een website helemaal opnieuw willen bouwen, ze zouden de neiging hebben om op de website van een ander te beginnen en iets te bouwen dat beperkt is in functionaliteit, betrouwbaarheid, gebruiksgemak en vooral creativiteit wanneer ze de nieuwste krachtige tools hadden die de limiet van het gebruik van gebruik en flexibiliteit in het gemak konden gebruiken, wat de limiet van het gemak in gebruik en flexibiliteit in het gemak zou hebben om te gebruiken. Als je een paar minuten de tijd hebt om dit boek te lezen en te leren wat ik je wil leren, of zelfs met mij persoonlijk over je doelen wil praten en wat begeleiding in de goede richting krijgt en gemotiveerd bent om te leren coderen en te schrijven van je eigen software, neem je dit boek mee naar huis en zet je wat tijd opzij om de volgende invloed, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige, krachtige en belangrijke webtoepassing ook te maken en je wil en te schrijven, precies te nemen wat je wilt en de behoeften van je doelgroep opbouwt.

Over mij: Ik ben een softwareontwikkelaar met een breed scala aan ervaring in C/C ++, Java, Python, HTML, CSS en JavaScript. Ik bouw websites die mensen willen gebruiken, willen bezoeken en zelfs verslaafd raken aan het gebruik alleen om tijd te leren, te herscheppen en te doden, en vooral, ik verkoop software. Als je een idee had om precies te hebben hoe je wilde dat een website eruit zou zien en functioneren, was je bereid me te ondersteunen, zodat ik aan mijn eigen behoeften kan voldoen terwijl ik de jouwe ontmoet, en je bent bereid om de kosten van het runnen van een website zelf te dekken, ik zou je de volgende YouTube, Tiktok, Twitter, Google, Google, Google of zelfs een high-tech beveiligings-app alleen u toegang hebben. In plaats van te proberen je mijn tijd te verkopen, probeer ik de jouwe te kopen: ik wil je er zelf over hebben om een ​​app (website) te bouwen met de informatie die al bestaat, en je te leren wat je nodig hebt om een ​​onafhankelijke softwareontwikkelaar, ondernemer te zijn, die een succesvolle carrière leidt op elk gewenste vakgebied. En laat me duidelijk zijn, de opleiding die ik je geef, zal informeel zijn. Je zou naar school kunnen gaan en dit allemaal leren met een formele opleiding, of dit boek zelfs op school lezen, je opdrachten voltooien en veel wegnemen van je opleiding, maar ik zal je niet formeel op de hot stoel zetten en je vragen om opdrachten te voltooien. Ik ben niet je professor, je kunt aan mij denken als een vriend die je wil begeleiden naar een carrière gedreven door je eigen persoonlijke succes. En ik verkoop je succes ook niet, je moet het met je tijd kopen. Leren te coderen heeft een steile leercurve en was nooit gemakkelijk, of zou zelfs moeten zijn. Je moet zo hard werken als je kunt en blijven proberen te falen en opnieuw te proberen, zelfs als je gefrustreerd bent om zelf apps te leren en te bouwen. Dat is in de aard van de code zelf. Code wordt uitgevoerd door een compiler die is ontworpen om de programmeerfoutmeldingen te geven, en deze zullen u leren hoe u moet coderen, zelfs als u de fout eenvoudigweg in uw zoekmachine kopieert en de voorbeelden van andere mensen leest. En ik moet zeggen dat je niet extreem rijk, slim, succesvol of zelfs gedetailleerd georiënteerd of georganiseerd hoeft te zijn om een ​​app te bouwen. De computer zorgt voor die organisatie voor u. Je hoeft alleen maar door de vallen en opstaan ​​te volharden, de focus te behouden en hard te werken aan wat je doet, en je zult een zeer succesvolle carrière hebben in het geheel van wat je doet.

Wie ik ben: Ik realiseer me dat het laatste deel meer ging over leren en je neemt een manier uit dit boek. Wie ben ik precies? Dat is een ingewikkelde vraag. Ik ben daar zelf onduidelijk over, omdat ik last heb van medische aandoeningen die het voor mij moeilijk kunnen maken om dit boek soms te coderen of te schrijven, terwijl ik uitdagingen presenteert met socialisatie- en identiteitsproblemen die mijn leven moeilijker maken als het gaat om het introduceren van mezelf. Kortom, als je dit boek leest, bracht je het naar huis omdat je er doorheen draaide en dacht dat het nuttig was, of zelfs als je net zo ver erin leest, ben ik een gelijkgestemde persoon die je wil zien slagen in alles wat je doet. Ik ben zelf een ingenieur, een softwareontwikkelaar en een student, en ik schrijf dit boek voor andere studenten die hun leven gemakkelijker willen maken door een handboek te hebben van de software die ze nodig hebben om hun leven gemakkelijker te maken door voorbeelden te geven die in elkaar passen als een grote puzzel in een werkende, nuttige, grote, functionele, samenhangende, samenhangende en boeiende app die het succes van de lijn van bedrijven kan stimuleren. Grotendeels, dit is wat ik doe: ik bouw apps om mezelf en andere mensen te helpen slagen. Ik ben ook een auteur, hoewel dit mijn eerste publicatie is die ik van plan ben te voltooien om mijn portfolio samen te stellen in een nuttig document, en ik ben ook een kunstenaar. Ik zal je dit toegeven, ik ben een soort vreemd persoon. Ik ben niet perfect, ik heb de wet gehad met de wet, zelfs ertoe leiden dat ik hogescholen en universiteiten verlaten en staten verlaten om te proberen een naam voor mezelf te maken met meer succes. Ik ben een vrouw van geboorte, ik draag make -up, maak foto's van mezelf, draag jurken en andere dameskleding en ik blijf me bewust van mezelf als een vrouw van nature. Ik heb in het verleden problemen gehad met andere mensen die hebben geleid tot worstelingen met het schrijven en bouwen van webapps, en ik bied mijn excuses aan dat ik dit boek niet eerder in handen heb kunnen krijgen: je had dit nodig. Je zult code willen lezen en schrijven die op mij lijkt en werkt als de mijne en hetzelfde doet, maar nog beter, want als je het je kunt veroorloven om dit boek te kopen in plaats van je toetsenbord te pureren zoals ik gewoon om een ​​boek te maken om er zelf geld voor te vragen, heb je de bronnen die je nodig hebt om succesvol te zijn in je leven. Ik had allerlei problemen met het opgroeien van familie, gezondheidstoestand, artsen, de media en de wet, en mijn code weerspiegelt diep de strijd die feminisme en vrouwelijke natuur is in een verdeelde en gefrustreerde wereld. Dit boek is echter iets waar ik diep om geef, mijn baby, mijn portfolio en mijn levensonderhoud, dus ik waardeer je overweging wanneer je de tekst naar huis neemt en er zorgvuldig overheen portrelt om van mij te leren. Houd er rekening mee dat ik niet perfect ben, dit boek zal fouten, revisies en nieuwe edities hebben, en je moet zo goed mogelijk met je logische brein denken om een ​​succesvolle ervaring met mijn schrijven te hebben. Begrijp ook dat ik goed voor je bedoel, zelfs als je voor uitdagingen wordt geconfronteerd tijdens het schrijven. Denk er zo over na: wanneer u gewoon een computersysteem kunt huren om alles te doen wat u zich kunt voorstellen in de digitale ruimte, alle informatie opslaat die u tegenkomt, analyseert en organiseren, en het komen begrijpen, zult u onvermijdelijk problemen ondervinden met de informatie die u inneemt en zelfs publiceert. Ik vertel je dit omdat ik dezelfde moeilijkheden tegenkom. Gebruik dit boek op eigen risico, werk samen met uw community en communities die voor u beschikbaar zijn om software te bouwen binnen een veilige setting, en neem dingen niet persoonlijk aan wanneer u faalt of zelfs op de verkeerde manier slaagt: zo ben ik zo ver gekomen, en waarom ik u deze tekst kan brengen en u kan slagen zonder de werking van de netwerk te doen. zal werken, internet. Je bent misschien niet erg bekend met wie ik ben met slechts een paar woorden, maar ik moedig je aan om verder te lezen, je zult me ​​leren kennen terwijl je me blijft lezen en begrijpen tijdens het bouwen van je eigen projecten om je werk te voltooien. Er zal geen huiswerk zijn met dit boek, zolang je professoren of leraren je niet toewijzen, maar ik moedig je ten zeerste aan om zelf een portfolio van projecten te bouwen terwijl je meegaat, evenals een Capstone -project dat laat zien hoe je kunt toepassen wat je hebt geleerd. Mijn Capstone -project is de basis voor het grootste deel van wat je in dit boek gaat lezen, omdat het code van mijn vorige projecten, code opneemt, die ik heb gemaakt en geleerd om methodisch met de hand te schrijven, en een breed scala aan ideeën en tips die me hebben geholpen om te slagen tot het punt waar ik een eenvoudige app kan spinnen die je volledig kan uitstrekken en lijkt en gedraagt ​​en gedraagt ​​een populaire app die je vriend of familie gebruikt, op het internet, op het internet, op het internet, of in het nieuws, of in het nieuws, of in het nieuws kunnen worden geactiveerd.

Wat dit boek is: Dit boek is een tutorial bij voorbeeld. U kunt hier code vinden, instructies om te leren coderen, informatie over foutopsporingcode en fouten op het oplossen van stappen, instructies voor het oplossen van een back-up van en opslaan van uw code, opnieuw inzetten als iemand uw code doorbreekt, uw code beveiligt, uw code beveiligt, uw code implementeert, uw code build, uw app en uzelf Software die u opbouwt in het absoluut beste licht om de meest aantrekkelijke mogelijk te zijn voor uw eindgebruikers, de bezoekers van uw website. In dit boek zal ik een aantal voorbeelden van softwareontwerp demonstreren met een focus op internet als platform en beveiliging. We zullen de leerervaring initiëren door een basisproject te bouwen met behulp van de UNIX -shell, met back -up- en scriptfuncties. Vervolgens zullen we een basisblogwebsite onderzoeken, onze blog upgraden met foto- en videofuncties en deze functies gebruiken om beveiligingsoplossingen te gebruiken met behulp van gratis software en onze server beveiligen met behulp van een pluggable authenticatiemodule (PAM). We zullen dan bestuderen en verwerken van bestanden, het verkennen van videobewerking, spraakdonatie, barcodescanning en optische karakterherkenning, naast andere concepten. Onderweg zullen we API's onderzoeken die ons zullen helpen onze software nuttiger en veiliger te maken, met gratis en betaalde opties. Onderweg zullen we fysieke beveiligings- en militante tools onderzoeken, zoals vuurwapens en munitieontwerp en -productie, waaronder vat- en repeaterontwerp, torentje en drone -ontwerp en andere opdrachtgevers die we zullen integreren met onze software op het bestaande netwerk om onze software te beschermen en zelfverdediging en weerbaarheid te tonen. We zullen onderweg pauzes nemen om games, 2D- en 3D -renderingmotoren te bouwen, en werken met ingebedde hardware in case study -voorbeelden van basisdimensionale renderingsoftware en een elektronische vibrerende massager die respectievelijk in siliconenrubber wordt gegoten. Onderweg zullen we ook machine learning -oplossingen gebruiken die al beschikbaar zijn om onze software beter te beveiligen. We zullen ook aandelenhulpmiddelen gebruiken die beschikbaar zijn voor het web om het proces te stroomlijnen en te beveiligen. Dit boek is een handleiding voor uw succes bij het bouwen van een webtoepassing en het integreren ervan met een professioneel netwerk van computer en ingebedde mechanische systemen, en over het algemeen een gids voor het bouwen van software en ingebedde hardware zonder achtergrondkennis of eerdere ervaring.

Wat dit boek niet is: Als je echt een website wilt hebben, kun je gewoon een eenvoudige winkel opzetten en verkopen wat je nodig hebt, een blog posten, foto's of video's posten, of anderszins zonder ooit een enkele regel code te schrijven. Dit boek is dat niet. Dit boek leert u hoe u software kunt bouwen die nuttiger, volledig uitgelicht, functioneel en veilig is dan alle software die u al kunt vinden, omdat het de nieuwste software implementeert die nog steeds prototypes is, kan duur zijn om te worden uitgevoerd op een schaal die oudere bedrijven werken en niet achteruit aanspreken, ingerichte bedrijven die zijn opgezet om geld te verdienen voor mensen die niet echt iets doen. Als u dit boek nauwlettend volgt, wilt u code, onderzoekscode schrijven, uw eigen apps bouwen en u zult geld verdienen met wat u doet. Ik zal geld verdienen uit dit boek, zelfs in vroege stadia, omdat het informatie bevat die mensen nodig hebben en willen lezen, en al kopen wanneer ze mijn apps kopen of gebruiken. Dit boek zal geen app voor u bouwen, maar het zal u in de goede richting wijzen en u bewapenen met de tools die u nodig hebt en de vaardigheden en tips die uw eigen succes zullen vergemakkelijken bij het bouwen van software voor internet, met elke regel code die u moet schrijven als voorbeeld, klaar om te worden samengevoegd tot software die u en uw supporters, klanten, families, familie, familie, families, en de mensen van de internet willen gebruiken.

Wat je zult leren: Dit boek leert u hoe u software kunt bouwen en verkopen, echt functionele, nuttige software, media -opname, beveiligingsfuncties zoals gezichtsherkenning, machine -leesbare zone barcodescannen, web -API's om video en foto's te verifiëren, op te nemen en te renderen en berichten te wisselen zoals Bluetooth en Near Field (NFC) -communicatie. In dit boek leert u hoe u een netwerkcomputer kunt gebruiken, gericht op Debian Linux, hoe u BASH -code kunt bouwen om het installeren en back -up van uw software een naadloze, geautomatiseerde bries te maken, hoe u Python -code kunt bouwen als backend om dynamische berichten te bedienen, style dingen gebruiken Natuurlijk gebruik van CSS -styles met BootStrap, en interactiviteit door netwerk -apparaten om te aanbieden. Andere doeleinden, ID -scannen, beeld- en video -moderatie, gegevensmicrotransacties om uw software veilig te houden, betalingsverwerking, cryptocurrency -handel, asynchrone taken en meer. U leert hoe u uw eigen Bluetooth -apparaten kunt bouwen, met batterijen, opladers, microcontrollers, circuits, motoren en sensoren, met soldeer, draad en 3D -geprinte evenals gegoten materialen. Ik zal demonstreren van 3D -ontwerpprincipes die zijn toegepast op additieve productie en gereedschap en het maken van die, zodat u uw eigen ingebedde, hardware -apparaten kunt produceren met geïntegreerde batterijen, opladers, elektronische circuits en functionele uitgangen. en netwerk ze met Bluetooth en het web. In het bijzonder zullen we twee casestudy's onderzoeken, een vibrerende massager en een zelfgemaakte vuurwapen, beide geprogrammeerd in OpenSCAD, die beschikbaar is als een grafische interface of opdrachtregelhulpprogramma en kan worden geïntegreerd in een web voor snellere resultaten. U leert hoe u een website vanaf de grond kunt bouwen en implementeren zonder voorafgaande ervaring, het functioneel, veilig, mooi, nuttig en vooral praktisch maakt. U leert hoe u machine learning en computer vision kunt gebruiken om een ​​site veilig en praktischer te maken, video en audio van uw website op te nemen, uw stem te doneren, muziek te maken en audio te moduleren om nuttige voorbeelden te maken, en hoe u de ruis doorbreekt door andere websites te gebruiken om het best mogelijke netwerk van websites te bouwen die u rechtstreeks aan u kunt koppelen om alle nuttige informatie te delen om alle nuttige informatie te delen om alle nuttige informatie te delen om alle nuttige informatie te delen, en nog meer belangrijker zijn om uw software en zaken te bieden. Dit boek zal het zwaarst gericht zijn op media, beveiliging en machine learning, de belangrijkste drie componenten die u zullen helpen nuttige software voor het web te bouwen door de juiste gebruikers te betrekken en de verkeerde te ontdoen op een manier die realistisch, praktisch, praktisch, hands on en boeiend is, hoewel ook automatisch en stevig. Dit boek leert Unix, met name Debian (Ubuntu), Bash Shell, Python, HTML, CSS, JavaScript en een aantal nuttige softwarepakketten voor Python -achtige verzoeken, evenals nuttige Bash -software zoals Git en FFMPEG. Ik zal je ook leren hoe je Cryptocurrency automatisch kunt verhandelen en betalingen moet doen in cryptocurrency of van reguliere betaalpassen, terwijl je zelfs je bezoekers een deel van je inkomsten betaalt als je ervoor kiest om dit te doen. Ik zal u leren hoe u ook via advertenties geld kunt verdienen met uw website, hoe u uw app voor zoekmachines kunt klaarmaken en het snel kunt maken, gerangschikt in de eerste rangorde voor wat uw klanten zullen zoeken om u te vinden, en zo veel mogelijk gemeenschappelijke zoekopdrachten te rangschikken. Ik zal u leren hoe u uw software kunt verkopen, adverteren, klanten aanspreken die op zoek zijn naar uw services en een naam voor uzelf op internet maken via wegen die al bestaan, zijn goedkoop en werken goed. Ik zal u leren hoe u uw gegevens kunt opslaan op cloudcomputers die voor u werken en uw gegevens goedkoop opslaan, hoe u een website kunt plannen en bouwen die doet wat uw gebruikers willen en wat u wilt, en hoe u uw gebruikers betrokken kunt houden door uw site een tik weg te nemen op hun telefoons met meldingen, e -mail, sms -berichten, telefoontjes, telefoontjes, telefoontjes, telefoongesprekken en meer mogelijkheid om uw gebruikers weer te geven aan uw website. Dit boek zal zich richten op de bruikbaarheid van het publiceren en distribueren van media in grote hoeveelheden, van tekst tot foto's tot video's tot audio, een goede indruk maken op eindgebruikers (uw klanten) en uzelf op elke manier verkopen die u doet om een ​​website te maken, een app die representatief is voor u en u, en maakt u, uw software en uw bedrijf op de best mogelijke manier. Je leert ook een paar tips en trucs van mij, van het coderen van tips, praktische ijdelheid zoals make -up en fotografie, modellering en acteren, en meer, wat belangrijk zal zijn om jezelf en uw bedrijf af te beelden in het best mogelijke licht met behulp van alle tools die u beschikbaar maakt terwijl u evenveel content nodig hebt als u een gezonde balans hebt om uw software te brengen om uw software te bewerkstelligen met geen meer inspanning, werk, werk, of geld, werk, werk, of geld, werk, werk dan nodig. Dit boek wordt "praktisch genoemdWebgebaseerd diep leren en beveiliging bij voorbeeld "Om een ​​reden: het gaat over leren coderen, specifiek voor het web, specifiek met een focus op beveiliging, vanuit een praktisch standpunt, met voorbeelden van werkende code die de praktische doelen bedient in de tekst. Verbetering, beeldtiteling en andere taken zoals voorspellingsstatistieken afkomstig van afbeeldingen, zoals de aard van de afbeelding als een authentieke, computer-overgedragen afbeelding, of een optische kopie (een foto van een afbeelding of afgedrukte foto). Face. Iedereen die software bouwt die onberispelijk veilig is, heeft enig idee van wat dit impliceert. Software is inherent onzeker omdat de apparaten en accounts die we gebruiken om deze te openen niet altijd tot onze beschikking zijn, ze kunnen in handen zijn van iedereen met slechte intentie voor de software en kunnen daarom een ​​risico vormen voor de software zelf. Dit is iets van de focus van dit boek. Een netwerkcomputer is standaard beveiligd met een lange sleuteltoken, genaamd en SSH of Secure Shell -sleutel, en is anders het best beveiligd met een webserver, omdat de webserver de open toegang biedt en de status van de kunstbeveiligingshulpmiddelen op de server zelf. De webserver heeft toegang tot de webbrowser van de gebruiker, wat misschien wel het krachtigste deel van het apparaat van de gebruiker is, omdat het de plaats is waar de gebruiker toegang heeft tot netwerksoftware. Deze toolkit kan tekst weergeven, de webpagina's die u ziet en kan ook afbeeldingen, audio en video opnemen (zoals een foto van een gezicht of een status -ID), kan lezen en schrijven naar Bluetooth -radio -apparaten en kunnen lezen en schrijven naar bijna veld transponder tags, goedkope sleutelkaarten, fobs, stickers, ringen, ringen, ringen, ringen en zelfs chip -implanties met unieke serie die wordt gelezen en getalateerd door een websites. Met behulp van alle tools tot uw beschikking, met dit boek zult u uzelf uitrusten met de kennis om een ​​veilige website te bouwen, en over het algemeen een veilig netwerk computersysteem dat voor u werkt, uw bieding doet en uiterlijk en voelt

Waar te beginnen: U bent van harte welkom om de sectie over te slaan waarmee ik dit boek begin, of een andere sectie, tot de exacte code die u nodig hebt, vooral als u ervaring hebt met codering voor of een van de bovengenoemde tools die ik in dit boek in detail zal beschrijven en use cases en praktische voorbeelden daarvan zal documenteren. Als je geen ervaring hebt met het schrijven van code, raad ik je ten zeerste aan al dit boek te lezen, en raad je vooral aan de vorige secties te lezen, om ervoor te zorgen dat dit boek geschikt is voor jou. Als dit boek niet geschikt is voor u, overweeg dan om het aan een vriend of familielid te schenken die misschien geïnteresseerd is in het leren over webontwikkeling, en overweeg zelfs te overwegen het terug te lenen en van hen te leren om de gaten in te vullen waar ik u als leraar faalde, of andere leraren deden voor mij. Begin waar u wilt, elk deel van dit boek zal nuttig zijn als u van plan bent een nuttige app te bouwen en bedenk dat de beste apps zijn gebouwd met de eindgebruiker in gedachten: ken uw klant. Nu ken je me, je kent dit boek en je bent klaar om te beginnen. Om te beginnen, pak je een computer (zelfs de goedkoopste laptop van een box -winkel, Amazon of een oude desktop werkt en zet hem op een manier die voor jou werkt.

Hoe dit boek te lezen: Tekst gemarkeerd, geeft aan dat de tekst in een opdrachtprompt hoort, waar u de code die u uitvoert, schrijft. De opdrachtprompt is zwaar op het toetsenbord gericht en vereist weinig om niet te klikken, uw workflow te versnellen en dingen gemakkelijker te maken.

Aan de slag: Laten we erin duiken. We beginnen met het bouwen van code op een lokale machine en beginnen zonder een website te bouwen die is verbonden met internet. Dit is veiliger om mee te beginnen, kost niets en is gemakkelijk voor u. Afhankelijk van uw besturingssysteem zal het in een bash -shell gaan een beetje anders zijn. Voor Mac OS raad ik aan om op dit moment een virtuele machine te installeren, omdat u de meeste compatibiliteit krijgt met een virtuele machine. Verschillende providers zoals VirtualBox en Paralells kunnen een virtuele machine voor u uitvoeren, hoewel het ook mogelijk is om Ubuntu rechtstreeks op de machine te installeren, als u liever een native omgeving gebruikt die wordt aanbevolen om een ​​snelle, gestroomlijnde ervaring te creëren. Als u Linux of Windows gebruikt, die ik aanbeveel, moet het vrij eenvoudig zijn om een ​​project te maken. Open uw terminal, pas de maatstaf aan zoals u wilt en begin met het volgen van stap 2. Als u Windows gebruikt, volg dan stap 1.

Stap 1: - alleen Windows -gebruikers Open de opdrachtprompt in Windows als beheerder en type wsl –stall

Stap 2: - Ga hier verder of sla stap 1 over als u Windows geen Windows gebruikt In een open terminal (afhankelijk van uw besturingssysteem, Ubuntu genaamd in Windows, Terminal in Mac of Linux, of een vergelijkbare naam), begint u met het maken van een project. We doen dit met het MKDIR -opdracht, dat een map creëert. Als u een map moet maken om uw project op te slaan, die wordt aanbevolen, gebruikt u de CD -opdracht om te wijzigen in de map en en en

CD/PATH/TO/DIRECTORY - Het pad is de mappen (bestanden) die voorafgaan aan uw bestemmingsmap, uw standaardpad is ~ of/home/gebruikersnaam (waarbij gebruikersnaam uw gebruikersnaam is). Typ CD of CD ~ om te wijzigen in de standaardmap ~ MKDIR Voorbeeld - Vervang "Voorbeeld" door de naam van de map

Nu heb je een werkmap voor je project. Omdat het zo belangrijk is om deze map te laten opslaan voor het geval u moet overschakelen naar een andere machine of de code die u schrijft moet implementeren, zodat het klaar is voor het web, zullen we een script bouwen om uw directory in de volgende stappen te ondersteunen. Maar het bouwen van een script kost een beetje code en code moet worden geautomatiseerd om zo nuttig mogelijk te zijn. Laten we dus een script bouwen om eerst scripts te bouwen. Laten we beginnen met het maken van het script en het uitvoerbaar maken. We zullen Sudo, Chmod en Touch hiervoor gebruiken en het script "Ascript" noemen.

sudo touch/usr/bin/ascript sudo chmod a+x/usr/bin/ascript sudo nano/usr/bin/ascript

Nu hebben we het script gemaakt, het uitvoerbaar gemaakt en zijn we klaar om het te bewerken. Nano is een teksteditor waarmee u tekst kunt bewerken zonder te klikken, wat veel eenvoudiger is dan het gebruik van een grafische gebruikersinterface. Gebruik Nano en vervolgens het pad naar het bestand om een ​​bestand met nano te bewerken. Om een ​​script te maken dat een script maakt, is het redelijk vergelijkbaar met het maken van ons script in de eerste plaats. We zullen dezelfde code gebruiken als hierboven, ter vervanging van de naam van het script, "Ascript" door een argumentparameter, $ 1. Hierdoor kunnen we het script aanroepen door eenvoudig Sudo Ascript Newscript te typen, op welk moment we elk nieuw script kunnen maken door "Newscript" te vervangen door de naam van uw script. De code in Nano zou eruit moeten zien als:

sudo touch/usr/bin/$ 1 sudo chmod a+x/usr/bin/$ 1 sudo nano/usr/bin/$ 1

En om Nano te sluiten, kunnen we de besturingstoets ingedrukt houden en op X drukken, dan y om aan te geven dat we het bestand opslaan en rendement raken. Nu in plaats van deze drie opdrachten te typen om een ​​script te bewerken, kunnen we sudo ascript AScript typen om het script opnieuw te bewerken. Dit werkt! En elk nieuw script kan eenvoudig worden uitgevoerd door het in de shell aan te roepen. Laten we ons werk nu opslaan: laten we een back -upscript schrijven om ons nieuwe script op te slaan en het vervolgens te ondersteunen in onze projectmap, terwijl het ook een back -up van het back -upscript back -up maakt.

sudo ascript back -up

Nu, in Nano:

sudo cp/usr/bin/backup/pad/naar/map/ sudo cp/usr/bin/ascript/path/to/map/map/

Waar/pad/naar/directory is het pad naar het project dat je hebt gemaakt met MKDIR. Later zullen we leren hoe we dergelijke herhaalde paden kunnen kopiëren met een lus en een lijst, die minder code is, maar laten we het voorlopig eenvoudig houden en een paar regels hebben. Sla het bestand op om dit script uit te voeren en back -up van uw code in nano met controle+x, y en retourneer en typ de onderstaande in uw shell

back -up

Als u überhaupt wordt gevraagd voor een wachtwoord tijdens het lezen van dit boek en het volgen van de shell, voer dan uw gebruikerswachtwoord correct in, u hebt drie pogingen voordat u de opdracht opnieuw moet uitvoeren. U kunt de pijlen op en neer gebruiken om opdrachten te herstellen en te bewerken, als u alles twee keer moet uitvoeren. Eenvoudig op en neer druk op en neer om een ​​opdracht te selecteren, voordat u de opdracht bewerkt met de rechter, linker pijlen en verwijderde toets en toetsenbord en het uitvoeren met retour.

Gefeliciteerd! Je bent erin geslaagd om een ​​geweldig back -upscript te maken dat twee belangrijke shell -scripts in je werkmap maakt. We kunnen de dingen later verplaatsen naarmate het project groter wordt, maar dit werkt voor nu. Laten we verder gaan met een back -up in de cloud, we zullen GitHub hiervoor gebruiken (hoewel er nog tal van andere Git -oplossingen zijn voor back -up, ze zijn allemaal over hetzelfde.) Git is een waaringscontrolesoftware waarmee u een back -up kunt maken van bewerkingen voor uw software terwijl u ze naar een server maakt, terwijl u ook in staat bent om hele kopieën van uw software achter een wachtwoord of sleutel te downloaden. Het is een belangrijke rol bij het opslaan van uw software, vooral omdat we migreren naar beveiligde Linux -instanties die soms breken wanneer een enkele regel code mislukt, waardoor u wordt vergrendeld terwijl uw code mogelijk niet wordt ondersteund als u geen kans krijgt om deze automatisch te ondersteunen, wat we zullen dekken.

Als u op dit moment nog geen Ubuntu -virtuele machine gebruikt, raad ik op dit moment aan dat u een Ubuntu -virtuele machine gebruikt, omdat het uw leven gemakkelijker zal maken bij het installeren van alle benodigde pakketten om een ​​werkende website te bouwen en de diepe leerbewerkingen op uw computer te preferent. We zullen de code in de nabije toekomst naar een webserver verplaatsen, maar we willen ervoor zorgen dat er minstens een paar beveiligingslagen achter onze webserver zijn die bestand zijn tegen phishing en een aantal Linux -pakketten gebruiken om dit te doen. Als u nog steeds Mac OS wilt gebruiken, bent u van harte welkom om de benodigde pakketten online te zoeken en te installeren, maar er zijn mogelijk geen alternatieven voor elk pakket dat dit boek of serie zal behandelen.

Laten we een paar opdrachten toevoegen om ons werk te plegen met het back -upscript door de opdracht Sudo ASCRIPT -back -up uit te voeren.

#… git toevoegen - allen git commit -m "back -up" git push -u oorsprong master

Breng nogmaals de controle van X om op te slaan.
sudo touch /usr/bin/ascript
sudo chmod a+x /usr/bin/ascript
sudo nano /usr/bin/ascript
Nu moeten we eenmalige configuratie uitvoeren voor dit project. Omdat het binnenkort een GIT -project zal zijn, hoeven we niet elke commando te typen telkens wanneer we vanuit een Git -repository worden geïmplementeerd, maar we zullen dit onder de knie krijgen wanneer we onze implementatievaringen schrijven. Laten we ervoor zorgen dat we ons in de juiste map bevinden en de GIT -repository initialiseren en SSH -toetsen genereren.

CD/PATH/TO/DIRECTORY Git Init Git Branch -m Master SSH-keygen

Nadat we SSH-keygen hebben getypt, moet de nieuwe sleutel worden opgeslagen in de huizenmap onder een map genaamd .ssh. Het wordt id_rsa.pub genoemd. Laten we deze sleutel vinden en kopiëren. Om het te zien,
sudo touch /usr/bin/$1
sudo chmod a+x /usr/bin/$1
sudo nano /usr/bin/$1
CD ~ cat .ssh/id_rsa.pub

Kopieer de tekst die wordt geretourneerd door de laatste opdracht en maak een account aan bij uw GIT -provider (idealiter GitHub), voordat u de SSH -toets aan uw account toevoegt. Zodra u een account hebt, klikt u op het menu Rechtsboven en voert u instellingen in, voordat u uw SSH -toets toevoegt in SSH- en GPG -toetsen onder toegang in het menu. Selecteer een SSH -toets toevoegen en voeg de uwe toe door deze in te plakken en een titel te geven, voordat u opslaan en terugkeren naar GitHub om een ​​nieuwe repository te maken. Dit is vergelijkbaar voor andere GIT -providers, u moet hun documentatie lezen. Geef uw repository in de nieuwe repository -configuratie een beschrijvende naam en beslis of u deze wilt publiceren, en zorg ervoor dat u nog geen bestanden voor opname configureert. Nadat de repository is gemaakt, kopieert u de kloon met SSH -URL en plakt u deze in de volgende opdracht.

Git Remote voeg git toe: //… (uw externe URL)
sudo ascript backup
Nu kunt u teruggaan naar uw repository met CD, u zult hiermee bekend zijn. Probeer nu uw back -upscript met back -up

Geweldig! Nu kunnen we echt coderen. Laten we Django installeren nu we een goede greep hebben op bash en git. Django laat ons onze software automatisch een back -up maken, Bash kan dit ook doen, maar Django moet een eenvoudiger veiligere implementatie hebben (het kan gemakkelijker worden uitgeschakeld en geconfigureerd).

Om software in Ubuntu te installeren, zullen we de sudo apt-get-opdracht gebruiken. Laten we eerst de software bijwerken en upgraden die we al hadden. Dit kan worden gedaan met sudo apt-get update en sudo apt-get-upgrade -y. Laten we vervolgens Python en onze virtuele omgeving, de thuisbasis van onze code, installeren met de volgende opdracht: sudo apt-get install python-is-python3 python3-venv
sudo cp /usr/bin/backup /path/to/directory/
sudo cp /usr/bin/ascript /path/to/directory/
Dit is alles wat je nodig hebt om met Django aan de slag te gaan in termen van software -installaties in de Ubuntu -instantie. Voor Windows en Linux zou dit vrij eenvoudig moeten zijn, maar voor Mac wilt u misschien een virtuele machine en Linux erop installeren met een gratis of betaalde virtuele omgeving zoals VirtualBox of Paralells Desktop en de bovenstaande stappen opnieuw te creëren om een ​​Ubuntu -omgeving in te stellen. Ubuntu is in dit geval van cruciaal belang omdat het de software is die de websites uitvoeren en hiermee websites kunnen hosten met alle bovengenoemde software.

Laten we in de Django graven.

Opnieuw in onze map, met CD:
backup
python -m venv venv # creëert de virtuele omgeving waar code wordt opgeslagen Bron Venv/bin/Activate # Activeert de virtuele omgeving PIP Installeer Django Django-Admin Start Project Mysite. # Waar Mysite het project is dat ik begin in mijn huidige map.

Creëert de virtuele omgeving waar code wordt opgeslagen

Activeert de virtuele omgeving

Waar Mysite het project is dat ik begin in mijn huidige map.

Django laat ons net op weg gaan, omdat Django de webserver host en alles doet wat we nodig hebben om een ​​eenvoudige lokale website in gebruik te nemen. Nu we Django hebben geïnstalleerd, laten we de instellingen een beetje bewerken om het te laten werken hoe we nodig zijn. Laten we eerst een nieuwe app maken

python management.py startapp feed

U zult merken dat de eerste app feed wordt genoemd. De app moet worden genoemd wat u maar wilt, en we zullen nieuwe apps maken, maar de naam van elke app moet consistent zijn telkens wanneer de app in de code wordt verwezen. Om een ​​nieuwe app toe te voegen, zullen we altijd de instellingen.py in de andere map bewerken, de app die is gemaakt, genaamd in StartProject, hierna app. Nano gebruiken,

nano app/settings.py

Zoek in de instellingen Installed_Apps en scheid de [] in 3 regels. Voeg 'feed' of de naam van uw app met vier spaties op de lege middellijn toe. Dit gedeelte van de instellingen.py moet eruit zien als:
# Geïnstalleerd_apps = [
    'voer',
]
Voordat we het vergeten, laten we testen dat Django werkt. Met behulp van de opdracht python management.py runserver 0.0.0.0:8000, kunnen we de server uitvoeren en vervolgens navigeren in een webbrowser op de computer die de code uitvoert naar http: // localhost: 8000 en een voorbeeldwebpagina zien (deze werkt!) Verhaalt de server met controle C, dezelfde als elke andere opdracht.

Laten we nu een python -code schrijven. Django heeft drie hoofdcomponenten, ze zijn allemaal volledig uitgevoerd door code. De componenten worden model, weergave en sjabloon genoemd en elk bevindt zich respectievelijk op een hoger en lager niveau voordat de webpagina aan de gebruiker wordt geleverd.

Het model is de code die informatie opslaat in de database voor het ophalen, sorteren en renderen.

De weergave bepaalt hoe het model wordt weergegeven, gemanipuleerd en gewijzigd, bijna elke weergave zal een model rechtstreeks gebruiken.

De sjabloon is de HTML -code met wat extra toeters en fluitjes genaamd sjabloontaal. De sjabloon wordt weergegeven door de weergave waar deze gevuld is met pythoncode en context zoals modellen en informatie (usuall strings en gehele getallen) uit de weergave.
cd /path/to/directory
git init
git branch -m master
ssh-keygen
Django heeft ook andere componenten, waaronder maar niet beperkt tot:

Instellingen, die de app configureren zoals we hebben besproken.

URL's, die patronen zijn die de gebruiker volgt om toegang te krijgen tot specifieke delen van de webtoepassing.
cd ~
cat .ssh/id_rsa.pub
Formulieren, die bepalen hoe informatie die naar de server wordt verzonden, wordt behandeld en weergegeven aan de database en aan de gebruiker. Dit vormen de basis van het verwerken van informatie aan de serverzijde en kunnen elk type informatie accepteren dat de computer slaat, met name tekstreeksen, nummers en true/false booleans (meestal selectievakjes).

Sjablonen, die HTML -code en sjabloontaal zijn en de kloof tussen Python en HTML overbruggen, wat betekent dat Python -informatie kan worden gediend als HTML -code die iedereen kan openen en een website met beperkte toegang kan beveiligen, terwijl Python -code toegankelijk maakt voor het web en nuttig voor verschillende doeleinden op een externe apparaat die niet in de buurt van de server hoeft te zijn.

Statische bestanden, die meestal JavaScript zijn en de bibliotheken die de server bedient en zijn gekoppeld aan de sjabloon.
git remote add git://… (your remote URL)
Mediabestanden, die de server serveert of extern wordt gehost, of gewoon naar de server worden geschreven voordat ze worden verwerkt en op een andere server (een emmer) voor hosting worden geplaatst.

Middleware, dat stukjes code is die tegelijkertijd met elke weergave worden uitgevoerd en worden beschouwd als "opgenomen" in de weergave.

Contextprocessors, die de context van elke weergave verwerken en worden gebruikt om extra context toe te voegen.

Tests, die valideren dat de gebruiker of het verzoek aan bepaalde vereisten voldoet voordat de weergave wordt weergegeven.

Consumenten, die bepalen hoe websockets omgaan en reageren op communicatie.

Admin, die wordt gebruikt om modellen te registreren, zodat ze in detail kunnen worden gemanipuleerd op de Django -admin -pagina, waar de database kan worden beheerd via een grafische interface.

Selderij, die asynchrone taken definieert, kunnen delen van de Django -code beginnen te draaien voordat ze onmiddellijk doorgaan naar de volgende taak of regel van code.

Django kan veel andere componenten hebben, die we hier in detail zullen bespreken. Er zijn tal van manieren om Django functioneler te maken, websockets toe te voegen, die snel, gestroomlijnde communicatiekanalen, selderij zijn, die asynchrone taken uitvoert, en een veelvoud aan andere stukken software voor het uitbreiden van Django, vooral in de viewfuncties, waar het grootste deel van de code wordt uitgevoerd. Bekijkfuncties zijn belangrijk omdat ze meestal elk stuk code verklaren dat specifiek is voor een specifiek URL -patroon of een gedeelte van de server.

Laten we eerst de view -functies verkennen. Bekijkfuncties beginnen met importcode die in de weergave wordt gebruikt en worden gedefinieerd met behulp van reguliere functiedefinities of klassen. De eenvoudigste weergaven worden gedefinieerd door de functiedefinitie DEF en retourneer een HTTPRESPONE met een basissjabloon. Laten we beginnen met het definiëren van een basisweergave om de tekst "Hallo wereld" te retourneren. Vergeet niet dat elke keer dat u code toevoegt na een instructie zoals def, als u, voor, enz., 4 spaties moet toevoegen voor elk van de voorgaande definities die u op uw functie wilt toepassen. We zullen ingaan op wat elk van deze betekent binnenkort.

Bewerk vanuit de map van onze site het bestand feed/views.py met nano en voeg de volgende regels toe aan het einde van het bestand.

van django.http import httpResponse Def Hallo (verzoek): Return httpResponse ('Hallo World')

Django's HttPresponse reageert met een tekstreeks, aangegeven met de opening en sluiting '. Telkens wanneer u informatie doorgeeft aan een functie of klasse, zoals aanvraag of een tekenreeks, moet u haakjes (, openen en sluiten) gebruiken.

Dit is niet alles wat we nodig hebben om onze mening nog te zien. Natuurlijk hebben we de server niet verteld waar de weergave precies is, we moeten nog steeds een pad definiëren waarmee de weergave moet worden weergegeven. Laten we beginnen met het definiëren van een basispad in app/urls.py en we zullen later in padgroepen komen.
python -m venv venv # Voeg in app/urls.py een regel toe na de importverklaringen na het begin met het importeren van de weergave die we zojuist hebben gemaakt.
source venv/bin/activate # van feed importweergaven als feed_views
django-admin startproject mysite . # Laten we nu het weergavepatroon definiëren. Bekijkpatronen hebben drie componenten, de padcomponent, die de server vertelt waar de weergave bestaat binnen de server (het URL -pad dat de gebruiker in de navigatiebalk typt om de webpagina in te voeren), de weergavecomponent waar de weergave is opgegeven, en een vriendelijke naam voor een andere weergave, is het gemakkelijk om met een sjabloon te werken bij het ophalen van een sjabloon wanneer het is om te werken met een sjabloon wanneer het is om met een sjabloon te werken wanneer het is om te werken met een sjabloon wanneer het is om te werken met een sjabloon wanneer het is om te werken met een sjabloon wanneer het is om te werken met een sjabloon wanneer het is om te werken met een sjabloon wanneer het is om te werken met een sjabloon wanneer het is om een ​​andere weergave te maken. Het is logisch om dingen op deze manier te doen en flexibel te zijn, omdat uw codebase een steeds veranderende omgeving zal zijn die flexibiliteit en improvisatie nodig heeft om waardevol en gemakkelijk mee te werken. Dit is hoe uw weergave eruit zal zien, u kunt dit toevoegen aan de urlpatterns = [sectie van app/urls.py. Het weergavepatroon wordt gedefinieerd met de drie hierboven beschreven componenten en een functie die pad wordt genoemd. Uw URL -patronen zijn een lijst, dus zorg ervoor dat u elk item er altijd in beëindigt met een komma, omdat dit elk scheidt. Elk item moet ook op een nieuwe regel gaan, opnieuw met vier spaties ervoor, net als de app in instellingen.py. We definiëren het eerste onderdeel van de weergave met een lege stringfunctie om een ​​weergave te maken die op de hoofdmap van de webserver wordt uitgevoerd. Uw urls.py zou er nu zo uit moeten zien:
van feed importweergaven als feed_views urlpatterns = [ Path ('', feed_views.hello, name = 'hallo'), ]

Dit is de basis voor het maken van een website met Django die volledig statisch is. Om een ​​meer dynamische website te maken waar we kunnen beginnen met het cachen van informatie, zoals afbeeldingen, video's, audio en meer, moeten we modellen gebruiken, die we vervolgens zullen verkennen. Laten we voor nu onze code controleren en de server uitvoeren. Voer de code op om de code te controleren:

python manag.py check
python manage.py startapp feed
Als er foutmeldingen zijn, moet u zorgvuldig de wijzigingen in uw app bekijken en kijken of er iets is dat moet worden opgelost, zoals een vreemde of gebrek aan ruimte, een extra teken, een niet -afgesloten string, een typefout, elk per ongeluk verwijderd teken of iets anders. Als je de foutmelding doorleest (als je er een hebt), zou je het pad moeten kunnen zien naar een bestand dat je hebt gemaakt of bewerkt met een regelnummer, dus kijk in dat bestand en regel en kijk of je alles kunt repareren dat er is. Als u het probleem hebt opgelost, voert u de bovenstaande opdracht opnieuw uit. Wanneer uw software klaar is om uit te voeren en werkt, ziet u de uitvoer "Systeemcontrole die geen problemen heeft geïdentificeerd". Nu ben je klaar om te gaan. Voer de server uit met:

python management.py runserver 0.0.0.0:8000

Open nu een webbrowser en navigeer naar http: // localhost: 8000. In uw weergave zou de tekst moeten worden geretourneerd in de haakjes en citaten van de HTTPRESPONSE -functie. Dit is slechts een fundamenteel voorbeeld, maar als je het zo ver hebt gehaald, begrijp je de basisprincipes van hoe Linux, Bash, Python en Django werken. Laten we dieper ingaan op wat databasemodellering en de kracht van een Python -klasse verkennen bij het opslaan van informatie. Vervolgens beginnen we een grip te krijgen op HTML en CSS voordat we onze site volledig aanbevolen, flexibel en veilig maken met behulp van JavaScript en Machine Learning.
nano app/settings.py
Klassen worden opgeslagen in de modellen.py van uw app. Nano gebruiken, app/modellen.py bewerken en een nieuwe klasse toevoegen. Een klasse wordt gedefinieerd met de klassendefinitie en wordt doorgegeven aan een superclass waar deze van, in dit geval modellen.model. De naam van de klasse komt na de klassendefinitie en na de klassendefinitie A: (colon) wordt gebruikt, voordat de attributen en functiedefinities die aan de klasse zijn gekoppeld hieronder worden aangegeven. Onze klas heeft een ID nodig die we kunnen gebruiken om deze op te halen en uniek te houden, en het heeft ook een tekstveld nodig om wat informatie op te slaan. Later kunnen we een tijdstempel, bestanden, booleans toevoegen (echte of valse definities die onze code kunnen helpen beslissingen te nemen over wat te doen met het model, en kunnen worden gebruikt om het te sorteren), een instantie om het model te binden aan een gebruiker die is aangemeld in de server, en meer. Laten we de onderstaande code uitpakken:

Van django.db Import modellen # De import die wordt gebruikt om onze klasse en de attributen te definiëren Class Post (Models.Model): # De definitie van onze klas zelf id = modellen.autofield (primary_key = true) # De ID van ons model, een automatisch gegenereerde sleutel waarmee we het model kunnen opvragen, uniek houden en nuttig is wanneer we met het model moeten communiceren zodra het is gemaakt. text = modellen.TextField (default = '') # het kenmerk onze klasse slaat in dit geval wat tekst op, die in gebreke zijn gebleven naar een lege tekenreeks.

De import die wordt gebruikt om onze klasse en de attributen te definiëren
INSTALLED_APPS = [
    'feed',
]
De definitie van onze klas zelf

De ID van ons model, een automatisch gegenereerde sleutel waarmee we het model kunnen opvragen, uniek houden en nuttig zijn wanneer we met het model moeten communiceren zodra het is gemaakt.

Het kenmerk onze klasse -opslag, in dit geval, wat tekst, die in gebreke zijn gebleven naar een lege tekenreeks.

Sluit en sla het bestand op zoals we eerder deden om te voltooien.

Er zijn veel andere velden en opties die we zullen onderzoeken wanneer we deze klasse bijwerken naarmate onze app evolueert, maar dit is de basisbehoeften om een ​​app te maken om wat tekst te plaatsen. Dit model werkt echter niet alleen. Zoals eerder beschreven, hebben we een aangepaste weergave en aangepast URL -patroon nodig om dit model te laten werken, en we hebben ook een formulier nodig samen met een sjabloon. Laten we eerst het formulier verkennen.

Om een ​​formulier te definiëren, bewerkt u app/forms.py met nano en voegt u de volgende regels toe. We hebben twee import nodig, onze formulierenklasse, evenals het model dat we hebben gemaakt (feed.models.post), een klassendefinitie vergelijkbaar met het model en een veld samen met een subklasse genaamd meta die het model zal definiëren waarmee de vorm samenwerkt. Het formulier kan ook een initialisatiefunctie hebben die deze instelt op basis van informatie in het verzoek, model of anderszins, we zullen dit later verkennen.

Modelformulieren zijn zo nuttig omdat ze een model kunnen maken of ook een model kunnen bewerken, dus we zullen ze voor beide gebruiken. Laten we er een in vormen definiëren. Py hieronder.

van Django Import Forms van feed.models import post Class Postform (Forms.Modelform): text = forms.charfield (widget = forms.TextArea) Class Meta: Model = post velden = ('text',)

Dit is de basisprincipes van hoe een vorm en model eruit zien. Dit modelformulier kan worden gebruikt om een ​​bericht te instantiëren of te bewerken, waarbij de tekst die het bevat te wijzigen. We zullen kijken naar de integratie van dit formulier in een weergave hierna. Laten we eerst de migraties maken en de database migreren, zodat onze code kan communiceren met het model wanneer het wordt uitgevoerd. Om dit te doen, voert u de volgende opdrachten uit:

python management.py makemigraties python beheren.py migreren

Dit duurt een minuut om uit te voeren, maar zodra dit het geval is, kunt u toegang krijgen tot het model in de weergaven, middleware of ergens anders in de software. Laten we doorgaan door te bekijken waar we ons model kunnen zien. Bewerk feed/views.py en voeg de volgende code toe, zoals opgemerkt. U hoeft niets toe te voegen na het # -teken, die code is opmerkingen die worden gebruikt om informatie over de code aan te geven. We beginnen met het importeren van ons model in de weergaven en het toevoegen aan een context waarin we het in een sjabloon kunnen weergeven als een lijst voor weergave. Vervolgens zullen we een sjabloon toevoegen waarbij we het formulier en het model kunnen weergeven met een knop om een ​​nieuw object te maken op basis van het model en het op de server te plaatsen. Dit klinkt ingewikkeld, dus laten we het stap voor stap zetten. Voordat we de weergave voltooien, laten we een sjabloon maken die het model gewoon weergeeft en ervoor zorgen dat we het kunnen zien door een nieuwe post in de shell te maken. Hier is hoe die weergave eruit moet zien:

van feed.models import post Van django.shortcuts import render, omleiding Van django.urls importeer omgekeerde omgekeerde def -feed (verzoek): posts = post.objects.all () # Quy alle berichten in de database tot nu toe return render (verzoek, 'feed/feed.html', { 'Posts': berichten, })

Vraag alle berichten tot nu toe in de database

Dit ziet er allemaal vrij eenvoudig uit totdat we tot de bodem zijn. Render, de waarde die wordt geretourneerd door de functie in plaats van in een HTTP -reactie zoals het vorige voorbeeld, neemt altijd een verzoek als de eerste invoer, accepteert een context (in dit geval de berichten in de database), die nu in de sjabloon kan worden weergegeven, en retourneert de sjabloon die in de functie is gedefinieerd. De sjabloon wordt een HTML -document met een beetje een taal genaamd Jinja2, die Python -informatie naar de HTML maakt.

Om te beginnen met het maken van sjablonen, maak je twee mappen in feed.

MKDIR -feed/sjablonen MKDIR -feed/sjablonen/feed

Bewerk vervolgens een sjabloon in de bovenstaande map, feed/sjablonen/feed en voeg de code toe voor dit voorbeeld. Laten we eens kijken naar de sjabloon voor dit voorbeeld.

Voer { % voor post in berichten %} {{post.text}} { % endfor %}

Dit is een heel eenvoudige sjabloon. Het definieert het openen en sluiten van HTML -tags, een documenttype -tag, een body -tag met een legendetitel, een break -tag die een kleine lijn over het scherm toevoegt, en een voor lus die elk bericht in de lijst met berichten weergeeft als paragraaf in de sjabloon. Dit is alles wat nodig is om berichten weer te geven, maar er zijn er nog geen in de database. Laten we wat maken met de shell. We kunnen de shell uitvoeren met management.py

python management.py shell

Laten we nu ons postmodel importeren

van feed.models import post

Vervolgens zullen we een eenvoudige post maken met een string en de shell verlaten. De string kan alles zijn, zolang het geldige tekst is.

Post.Objects.Create (text = 'Hallo World') Uitgang()

Ten slotte moeten we een URL -patroon aan onze feed toevoegen. Omdat onze feed -app meerdere URL's gebruikt en we de bestandsgroottes klein willen houden, laten we een lokale urls.py maken in onze feed -app die er zo uitziet:

Van django.urls importpad van . Importweergaven urlpatterns = [ pad ('', views.Feed, name = 'feed'), ]

We zullen ook de urls.py in de basis -app moeten bewerken, wat we ook besloten het te noemen, dit was de eerste directory die we hebben gemaakt. Bewerk app/app.py en voeg het volgende toe aan de URL -patronen

Van django.urls import is # bovenaan urlpatterns = [ #... vorige code hier PATH ('feed/', include (('feed.urls'), namespace = 'feed')), ]

bovenaan

... vorige code hier

Wanneer we de server nu uitvoeren met python management.py runserver, zien we de pagina die we hebben gemaakt omdat we het model, de weergave en het url -patroon hebben, samen met items in de database. Laten we vervolgens het formulier implementeren dat we hebben gemaakt en beginnen met het maken van onze eigen berichten. Maar voordat we te veel code schrijven, laten we een back -up maken met het script dat we eerder hebben geschreven, back -up. Voer dit script in de shell uit, wacht een paar ogenblikken en alle code wordt ondersteund door onze GIT -repository.

back -up

Het implementeren van het formulier is relatief eenvoudig. We zullen ons formulier importeren, een post -aanvraaghandler toevoegen aan de weergave en het bericht opslaan in de database voordat we naar dezelfde weergave worden gericht. We kunnen de omleidingsfunctie gebruiken die we al hebben geïmporteerd, en een andere functie genaamd Reverse om de URL voor het weergavepatroon te krijgen. We zullen dit opvragen met de tekenreeks 'Feed: Feed' omdat de naamruimte van het opgenomen patroon feed is en de weergave ook Feed wordt genoemd.

van feed.forms import postform def -feed (verzoek): posts = post.objects.all () # Quy alle berichten in de database tot nu toe if request.Method == 'Post': # behandel het postverzoek Form = postform (request.Post) # Maak een instantie van het formulier en sla de gegevens op if form.is_valid (): # valideer het formulier form.save () # Sla het nieuwe object op Return Redirect (Reverse (Reverse ('Feed: Feed')) # Redirect naar dezelfde URL met een GET -verzoek return render (verzoek, 'feed/feed.html', { 'Form': postform (), # zorg ervoor dat u het formulier in de context doorgeeft, zodat we het kunnen weergeven. 'Posts': berichten, })

Vraag alle berichten tot nu toe in de database

Behandel het postverzoek

Maak een exemplaar van het formulier en sla de gegevens op

Valideer het formulier

Sla het nieuwe object op

Direct door naar dezelfde URL met een GET -verzoek

Zorg ervoor dat u de vorm in de context doorgeeft, zodat we het kunnen weergeven.

Tag in HTML en het weergeven van het formulier in de HTML -sjabloon met een verzendknop. We hebben ook een CSRF -token nodig, een token dat voorkomt dat externe sites op het formulier worden geplaatst zonder eerst een pagina te laden.

Voer { % csrf_token %} {{ formulier }} Nieuwe post { % voor post in berichten %} {{post.text}} { % endfor %}
from django.http import HttpResponse

def hello(request):
    return HttpResponse('hello world')
Laten we dit afbreken. Er is een nieuwe formulierklasse, een token, het formulier zelf en een verzendknop. Vrij eenvoudig, maar als we er naar kijken, willen we het misschien beter laten lijken. Het werkt, we kunnen nieuwe berichten met het formulier plaatsen en ze zijn nu opgeslagen in de database. Er zijn hier een paar dingen aan de hand. We gebruiken HTML -tags om te verklaren dat het document een HTML -document is, we gebruiken een sjabloon -tag ({ %… %}) om het token voor het formulier weer te geven, en een andere, {{…}} om het formulier weer te geven. We hebben ook een lus om de tekst weer te geven met behulp van bloktags en een sjabloon -tag. Bloktags zijn echt belangrijk omdat we kunnen definiëren hoe secties van de sjabloon worden weergegeven, en sjabloontags vormen de basis van hoe we variabelen in onze code plaatsen.

Nu moeten we onze app er beter uit laten zien, want voor nu ziet het er echt eenvoudig uit. We kunnen dit doen door CSS te gebruiken, inline, of in klassen die aan elk object in het document zijn gekoppeld. CSS is echt leuk omdat het alles op de pagina vertelt hoe het eruit moet zien en het er echt goed uit kan laten zien. Er zijn een paar bibliotheken die dit kunnen doen, maar mijn persoonlijke is bootstrap.

getBootstrap.com/

Maak een nieuwe map genaamd sjablonen met MKDIR -sjablonen en bewerk vervolgens sjablonen/base.html.

Het zou er zo uit moeten zien:

{ % Block Body %} { % endblock %}

Zorg ervoor dat u de CSS en JavaScript, de .css- en .js -bestanden kopieert, omdat we het JavaScript nodig hebben om onze site in de toekomst functioneler te maken.
from feed import views as feed_views
Laten we nu terugkeren naar de bash -shell en een snelle opdracht uitvoeren. Vergeet niet dat als u ooit toegang moet krijgen tot de virtuele omgeving, de bron Venv/Bin/Activeer Typ. Hiermee kunt u Python -pakketten lokaal installeren op een manier waarmee Django toegang heeft. Om onze formulieren te geven die worden gegenereerd door Django Bootstrap -klassen, zullen we een Python -pakket gebruiken genaamd Crispy Forms. We kunnen dit downloaden met de volgende opdracht

PIP Installeer Django-Crispy-Forms

Zodra dit is geïnstalleerd, voegt u het toe aan de instellingen.py
from feed import views as feed_views

urlpatterns = [
    path('', feed_views.hello, name='hello'),
]
Geïnstalleerd_apps = [ # ... vorige code hier 'Crispy_forms', ]

… Vorige code hier

Nu, terug in onze toevoersjabloon, kunnen we enkele dingen verwijderen. Laten we het begin en einde van het document verwijderen en vervangen door overerving uit onze basissjabloon, met behulp van Extends en de blokdefinitie. We zullen ook een sjabloonfilter importeren met load en een sjabloonfilter aan het formulier toevoegen. Laten we ten slotte een bootstrap -klasse toevoegen aan de knop op het formulier om deze meer op een knop te laten lijken. Dat zou er zo uit moeten zien:
python manage.py check
{ % verlengt 'base.html' %} { % Block Body %} { % laden Crispy_forms_tags %} { % csrf_token %} {{Form | Crispy}} Nieuwe post { % voor post in berichten %} {{post.text}} { % endfor %} { % endblock %}

Mooi! Dat is al nogal wat code. Vervolgens moeten we het testen en ervoor zorgen dat we kunnen zien dat alles er mooi uitziet, en er ook zeker van dat alles goed werkt. Voer de server uit volgens eerdere instructies en zorg ervoor dat de site er uitziet en goed werkt. Geweldig werk! U bent klaar om door te gaan naar de volgende stap, waarin we gebruikersaanmeldingsfunctionaliteit toevoegen met vergelijkbare URL's, formulieren, weergaven en sjablonen. De basissjabloon is belangrijk, en we zullen deze blijven wijzigen en wijzigingen aanbrengen als dat nodig is, maar laten we ons nu concentreren op het veiliger maken van onze site, door gebruikers in staat te stellen in te loggen met een gebruikersnaam en toegangscode, en uiteindelijk nog belangrijker informatie die uw app beveiligd houdt en uw eigen account alleen toegankelijk door u.

Om dit te doen, moeten we het gebruikersmodel gebruiken ingebouwd in Django. Het gebruikersmodel is een databasemodel, zoals onze post, dat kan worden weergegeven om een ​​gebruiker op de website te loggen. In de toekomst, voordat we de site op internet implementeren, zullen we dit model uitbreiden met andere modellen die eraan worden toegeschreven en extra beveiligingsmaatregelen bouwen voor de login die bestand zijn tegen phishing. We zullen beginnen met het gebruik van enkele ingebouwde inlogformulieren die Django biedt. Laten we eerst een nieuwe app maken die we zullen gebruiken om de sjablonen en weergaven voor de Basic Login -pagina weer te geven. We zullen ook andere apps maken om de voortdurende inloguitdagingen weer te geven om de app te beveiligen, waaronder een pincode, gezichtsherkenning, nabije veldcommunicatie, externe apparaten, multi -factor authenticatie en vingerafdrukherkenning.
python manage.py runserver 0.0.0.0:8000
We hebben het al gehad over het starten van een app. Van onze directory, binnen de virtuele omgeving, pass beheren.py deze argumenten

python manag.py startapp gebruikers

Nu moeten we een directory hebben voor de nieuwe app. Laten we beginnen met het maken van een weergave in die map die overeenkomt met de gebruikersaanmelding. Django heeft ingebouwde weergaven voor gebruikersaanmeldingen, maar deze zijn niet geschikt voor ons omdat we een aangepaste weergave nodig hebben, die bij voorkeur met een definitie wordt gedaan.

In deze weergave zullen we beginnen met het controleren van een postverzoek, PASS -verzoek. Post naar een Loginform geïmporteerd vanuit Django, de gebruikersaccount verifiëren en de gebruiker inloggen voordat u deze naar onze feed -app omgeleid.

Voeg in gebruikers/views.py de volgende code toe
from django.db import models # Van django.shortcuts import render, omleiding
Van django.urls importeer omgekeerde omgekeerde
Van django.contrib.auth.forms import AuthenticationForm, setPasswordForm
Van django.contrib.auth importeren authenticaat, uitloggen
Van django.contrib.auth importeer login als auth_login
Van django.contrib Import berichten

def -login (verzoek):
    if request.method == "post":
        gebruikersnaam = request.Post ['gebruikersnaam'] # Haal de gebruikersnaam en het wachtwoord uit het postverzoek
        wachtwoord = request.post ['wachtwoord'] # authenticeer de gebruiker
        user = authenticate (gebruikersnaam = gebruikersnaam, wachtwoord = wachtwoord)
        Als gebruiker:
            auth_login (verzoek, gebruiker, backend = 'django.contrib.auth.backends.modelbackend'))
            berichten.success (verzoek: 'Uw wachtwoord is geaccepteerd. Ga door met')
            Return Redirect (Reverse ('Feed: Feed'))
        anders: berichten.warning (verzoek, 'gebruikersnaam of wachtwoord onjuist. Probeer het opnieuw')
    Return Render (Request, 'Users/Login.html', {'Form': AuthenticationForm ()})
class Post(models.Model): # Haal de gebruikersnaam en het wachtwoord uit het postverzoek
    id = models.AutoField(primary_key=True) # Authenticeer de gebruiker
    text = models.TextField(default='') # Dit is alles wat je nodig hebt voor een basisaanmeldingsweergave. Laten we nu een formulier voor de weergave maken door de basissjabloon uit te breiden. We beginnen met het maken van een nieuwe map voor sjablonen in de map Gebruikers.
MKDIR -gebruikers/sjablonen MKDIR -gebruikers/sjablonen/gebruikers

Nu moeten we gebruikers/sjablonen/gebruikers/login.html kunnen bewerken. Terwijl we bezig zijn, maken we een sjabloon om de gebruiker ook aan te melden.

nano -gebruikers/sjablonen/gebruikers/login.html

Nu, in de sjabloon,

{ % verlengt 'base.html' %} { % laden Crispy_forms_tags %} { % blokinhoud %} { % csrf_token %} Inloggen {{Form | Crispy}} Login { % endblock %}

Dit is de basisprincipes van een inlogsjabloon. Het is echt net als de andere sjabloon in structuur, maar het ziet er een beetje anders uit wanneer het wordt weergegeven. We kunnen deze code kopiëren om een ​​andere zeer vergelijkbare sjabloon te bouwen genaamd Register.html, waar we de formulering zullen wijzigen en een nieuw formulier gebruiken dat we bouwen. Laten we eerst de sjabloon maken. Gebruikers/sjablonen/gebruikers/register.html bewerken en de volgende code toevoegen:

{ % verlengt 'base.html' %} { % laden Crispy_forms_tags %} { % blokinhoud %} { % csrf_token %} Maak een account aan {{Form | Crispy}} Register { % endblock %}

Laten we nu een formulier bouwen voor onze gebruikersregistratie en teruggaan naar de weergaven voordat we onze gebruikersaanmeldingen upgraden met een model. We zullen dit formulier fundamenteel maken om mee te beginnen, maar nemen in de toekomst meer details en beveiligingsfuncties op, zoals overeenkomsten en Captcha. Bewerk de formulieren met nano -gebruikers/formuliers.py en voeg de volgende code toe.

van Django Import Forms Van django.contrib.auth.models importeer gebruiker van django.contrib.auth.forms import userCreationForm Class UserRegisterForm (UserCreationForm): E -mail = formulieren. Emailfield () Class Meta: model = gebruiker fields = ['gebruikersnaam', 'e -mail', 'wachtwoord1', 'wachtwoord2']
from django import forms
from feed.models import Post

class PostForm(forms.ModelForm):
    text = forms.CharField(widget=forms.Textarea)
    class Meta:
        model = Post
        fields = ('text',)
Dus we hebben hier nog een vorm, wat redelijk eenvoudig werkt. Het is een gebruikersregisterformulier met een gebruikersnaam, e -mail en wachtwoord, evenals een bevestigingswachtwoordveld. Merk op dat dit formulier de reguliere vorm niet uitbreidt. Eén veld is precies hetzelfde gedefinieerd en de klasse meta definieert het model dat de vorm overeenkomt met de rest van de informatie die naar de vorm wordt geschreven. Het meeste hiervan bestaat al in Django's ingebouwde UserCreationForm, dus we zullen dat gebruiken als basis voor de klasse (doorgegeven in de haakjes).

Vervolgens zullen we de weergave onderzoeken om een ​​gebruiker te registreren, nu we een formulier en een sjabloon hebben. Dit is een modelform, net als die in de nieuwe postweergave. Gebruikers/views.py bewerken en de volgende code toevoegen:

# ... importeert Van .forms importeer userRegisterForm def register (verzoek): if request.method == "post": Form = UserRegisterForm (Request.Post) if form.is_valid (): user = form.SAVE () messages.success (verzoek, 'Welkom bij de app, {}.'. Format (user.UserName))) Return Render (Request, 'Users/Register.html', {'Form': UserRegisterForm}))
python manage.py makemigrations
python manage.py migrate
… Importeren

Dit is alles wat we nodig hebben om een ​​gebruiker te laten registreren, maar we moeten meer informatie hebben. We willen weten hoe de gebruiker zich heeft geregistreerd, hoe laat ze voor het laatst op de site waren, wat informatie over hen, zoals een biografie, tijdzone, enz. Ook moeten we ons feedmodel bijwerken, post, om rekening te houden met het gebruikersmodel en een toeschouwingsberichten aan elke gebruiker. Om dat te doen, zullen we de modellen.py bijwerken in beide apps. Laten we beginnen met het bewerken van het voedingsmodel. Het zou er nu zo uit moeten zien:

Van django.db Import Modellen #… imports Van django.contrib.auth.models importeer gebruiker Class Post (Models.Model): id = modellen.autofield (primary_key = true) Author = Models.ForeignKey (gebruiker, on_delete = modellen.cascade, null = true, blank = true, gerelateerd_name = 'posts') # Toevoegen in deze regel text = modellen.TextField (default = '')
    posts = Post.objects.all() # … Importeren
Voeg deze regel toe

Let op de tweede regel die aan het bestand is toegevoegd. Dit is een buitenlandse sleutel, die elk bericht per bericht per bericht toeschrijft, zodat we ervoor kunnen zorgen dat we de berichten op een gebruikers-per-gebruikersbasis opslaan en er kan geen bericht worden gemaakt zonder deze aan een gebruiker toe te schrijven. We definiëren deze buitenlandse sleutel met de klasse die het vertegenwoordigt, een verwijderen van argument om ervoor te zorgen dat berichten worden verwijderd met gebruikers, nul- en lege argumenten om ervoor te zorgen dat we de gebruiker indien nodig kunnen verwijderen en om tegemoet te komen aan het ontbreken van een gebruiker op berichten die we al hebben gemaakt, en een gerelateerde naam, die we kunnen gebruiken om te verwijzen naar de postobjecten die de gebruiker maken. Deze gerelateerde naam, in tegenstelling tot Post.Author, de auteur van het bericht, geeft ons de gebruiker die het bericht zelf heeft gepost. We kunnen nu de berichten krijgen die een gebruiker heeft gemaakt door gebruiker.posts.all () of author.posts.all ().

Laten we nu onze aanmeldingen veerkrachtiger maken. We kunnen onze site al veel minder kwetsbaar maken voor phishing door eenvoudigweg het aantal keren te beperken dat we een inloggen op de site toestaan, dit is vrij eenvoudig. Laten we ook eerder wat informatie over elke gebruiker opslaan terwijl we onze app blijven ontwikkelen. Gebruikers/modellen.py bewerken, voeg de volgende code toe.

van django.db importmodellen Van django.contrib.auth.models importeer gebruiker van django.utils import timezone Klasse profiel (modellen.model): user = modellen.onetoOnefield (gebruiker, on_delete = modellen.cascade, null = true, blank = true, gerelateerd_name = 'profiel') Account_created = modellen.datetimeField (standaard = timeZone.now) last_seen = modellen.datetimeField (standaard = timeZone.now) can_login = modellen.datetimeField (standaard = timeZone.now) preferred_name = modellen.charfield (max_length = 20, default = '', null = true, blank = true) bio = modellen.TextField (blank = true, default = '')

Merk op dat dit model redelijk vergelijkbaar is met het postmodel. We hebben een extra import, tijdzone, waarmee we standaardinstellingen kunnen instellen op de datetime -velden, en we hebben ook een Characterfeild en Textfield zoals het bericht. Het gebruik van al deze tijdstempels helpt ons om de site te beveiligen en het gebruik ervan te begrijpen, en de tekstvelden laten ons informatie over elke gebruiker of auteur op de website weergeven. Het OnetoOneField moet de enige kleine overweging zijn, het gedraagt ​​zich precies hetzelfde als een Foreockey, maar met slechts één per daaropvolgend model. Op deze manier heeft de gebruiker slechts één profiel, terwijl hij misschien veel berichten heeft.
mkdir feed/templates
mkdir feed/templates/feed
Laten we nu onze login verbeteren en weergaven voor het profiel registreren. Bewerk eerst gebruikers/views.py en focus op de registerweergave:

# ... importeert Van .forms importeer userRegisterForm def register (verzoek): if request.method == "post": Form = UserRegisterForm (Request.Post) if form.is_valid (): user = form.SAVE () Profiel.objects.create (user = user) # Zorg ervoor dat u deze regel toevoegt om een ​​profiel voor de gebruiker te maken messages.success (verzoek, 'Welkom bij de app, {}.'. Format (user.UserName))) Return Render (Request, 'Users/Register.html', {'Form': UserRegisterForm}))

… Importeren
Zorg ervoor dat u deze regel toevoegt om een ​​profiel voor de gebruiker te maken

Dit maakt eenvoudig een profiel voor de gebruiker, zonder een van de informatie in te vullen. Nu willen we ervoor zorgen dat het gebruikersaccount niet te vaak kan worden ingelogd, of in ieder geval niet te vaak worden geprobeerd, dus laten we de inlogweergave bijwerken.

# ... importeert van .modellen importprofiel importeren van django.utils import timezone DateTime importeren def -login (verzoek): if request.method == "post": gebruikersnaam = request.Post ['gebruikersnaam'] wachtwoord = request.Post ['wachtwoord'] user = authenticate (gebruikersnaam = gebruikersnaam, wachtwoord = wachtwoord) Als user en user.profile.can_login <timeZone.now (): # Merk op dat we nu controleren of de gebruiker inlogt auth_login (verzoek, gebruiker, backend = 'django.contrib.auth.backends.modelbackend')) berichten.success (verzoek: 'Uw wachtwoord is geaccepteerd. Ga verder.') Return Redirect (Reverse ('Feed: Feed')) anders: # als de login niet succesvol was, berichten.warning (verzoek, 'gebruikersnaam of wachtwoord onjuist. Probeer het opnieuw.') user = user.objects.filter (gebruikersnaam = gebruikersnaam) .first () # Dit is het deel waar we het gebruikersprofiel bijwerken Als gebruiker: profiel = user.profile profile.can_login = timezone.now () + datetime.timedelta (seconden = 15) # zodat ze niet opnieuw kunnen inloggen voor een paar seconden profile.Save () Return Render (Request, 'Users/Login.html', {'Form': AuthenticationForm ()})
python manage.py shell
… Importeren

Merk op dat we nu controleren of de gebruiker kan inloggen

Als de login niet succesvol was,
from feed.models import Post
Dit is het deel waar we het gebruikersprofiel bijwerken

Dus ze kunnen niet opnieuw inloggen voor een paar seconden

Dit is het fundamentele fundamentele beveiliging. Zorg ervoor dat de site niet kwetsbaar is voor iemand die gewoon elke mogelijke wachtwoordcombinatie probeert, of zelfs een paar daarvan tegelijkertijd. Dit zal niet frustrerend zijn voor de gewone gebruiker die hun toegangscode kent en gewoon inlogt op een paar apparaten, maar het zal talloze phishing -robots uit de app houden. Merk op dat we een IF -instructie hebben toegevoegd met een variabele, can_login, dat zou een tijd in het verleden moeten zijn en deze bijwerken met elke mislukte login met dezelfde gebruikersnaam. Op deze manier kan een kwaadaardige gebruiker geen wachtwoord nergens zo snel raden. Het aantal seconden in de DateTime.Timedelta () kan ook worden bijgewerkt en de website zal veerkrachtiger zijn en toch iets minder bruikbaar met meer seconden. Ik raad 15 aan om mee te beginnen.
Post.objects.create(text='hello world')
exit()
Vergeet niet dat we een back -upscript hebben opgebouwd om ons werk op te slaan, dus laten we doorgaan en een back -up maken van wat we tot nu toe hebben om ervoor te zorgen dat we alles hebben opgeslagen. Voer de opdracht uit:

sudo back -up

Nogmaals, dit zal uw werk tot nu toe besparen. Ik raad aan om frequente back -ups uit te voeren om uw werk op te slaan en u wilt misschien zelfs automatisch een back -upopdracht uitvoeren. U kunt dit doen met behulp van een UNIX -hulpprogramma genaamd Cron. Om dit hulpprogramma te activeren, voert u de volgende opdracht uit en voert u uw wachtwoord in:
from django.urls import path
from . import views

urlpatterns = [
    path('', views.feed, name='feed'),
]
sudo crontab -e

Als u nog niet optie 1 voor Nano selecteert, moet de teksteditor waarmee u al bekend bent en naar de onderkant van het bestand bladert met behulp van de pijltoetsen. Voeg de volgende regel toe:

0 * * * * sudo back -up
from django.urls import include # Cron gebruikt het formaat minuut, uur, dag van maand, maand, dag van de week, waarbij een * of een nummer vertegenwoordigt wanneer het commando moet worden uitgevoerd. Met behulp van een 0 voor de minuut en * voor de rest van de opties kunnen we een opdracht uitvoeren op de eerste minuut van elk uur aan het begin van de minuut. Hierdoor kunnen we de code automatisch maken. Alle taken van Cron wanneer ze worden uitgevoerd met Sudo Run als root, dus we hoeven niet elk uur een wachtwoord in te typen.
    # Om het gemakkelijker te maken om onze code te ondersteunen zonder een wachtwoord te gebruiken, laten we het wachtwoord voor onze back -upopdracht uitschakelen. We zullen dit doen door de volgende opdracht uit te voeren en een wachtwoord in te voeren:
Sudo Visudo

Laten we nu naar de onderkant van het bestand bladeren en een andere regel toevoegen:

All All = nopasswd: /bin /backup
backup
Hiermee kunnen we de opdracht "back -up" als elke gebruiker uitvoeren, zonder een wachtwoord. Het formaat hiervoor is eenvoudig, prefix gewoon de lijn met "all all = nopasswd:/bin/" en eindig met de opdracht, bijvoorbeeld/bin/backup, die bestaat in/usr/bin/.

Laten we nu gaan werken met e -mail. E -mail is echt belangrijk voor websites, omdat het een manier is om een ​​website veiliger te houden, te controleren of gebruikers echte mensen zijn, en zelfs marktproducten of diensten aan klanten. Veel mensen die internet bezoeken, controleren dagelijks hun e -mail en ontvangen allerlei marketingmails over producten en diensten waarin ze geïnteresseerd zijn. Er zijn een paar opties als het gaat om het inschakelen van e -mail op een Django -website, en u bent van harte welkom om te kiezen welke het beste voor u werkt.

Eerst kunt u betalen voor een e -mailservice waarmee u e -mail vanuit uw domein kunt verzenden en minimale code vereist. Er zijn veel services die dit aanbieden, zoals Google Workspace, SendinBlue, MailGun en meer.
    posts = Post.objects.all() # Anders bent u goed uit het bouwen van uw eigen e -mailservice op uw server helemaal opnieuw. Ik raad deze optie aan, hoewel het meer code is en mogelijk speciale hosting vereist. U kunt waarschijnlijk niet een e -mailserver starten vanaf uw thuiscomputer, dus laten we doorgaan en de configuratie en code onderzoeken om e -mail te verzenden voordat we een server in de cloud starten en onze eigen mailserver erin maken.
    if request.method == 'POST': # Bewerk eerst instellingen.py met de volgende opdracht:
        form = PostForm(request.POST) # nano app/settings.py
        if form.is_valid(): # Waar App de naam is van de app die u hebt gemaakt met StartApp.
            form.save() # Voeg de volgende regels toe:
        return redirect(reverse('feed:feed')) # Site_Name = 'Django App'

E -mail_backend = 'django.core.mail.backends.smtp.emailbackend'
E -mail_host = 'localhost'
E -mail_port = 587
E -mail_use_tls = true
E -mail_adress = gebruikersnaam@server.com '
E -mail_host_user = 'gebruikersnaam'
E -mail_host_password = config ['e -mail_host_password']
Default_from_email = '{} <{}>'. Format (site_name, e -mail_host_user)
        'form': PostForm(), # Zorg ervoor dat u deze wijzigt wanneer u klaar bent om uw app te implementeren, we zullen dit later opnieuw bezoeken. De instelling E -mail_adress moet de e -mail zijn die u wilt verzenden en het wachtwoord (e -mail_host_password) moet worden ingesteld op het wachtwoord dat u voor de server genereert. Ik laad het wachtwoord uit een configuratiebestand om het uit de code te houden met behulp van de volgende logica, boven deze regels in settings.py:
Importeer OS import JSON met open ('/etc/config.json') als config_file: config = json.load (config_file)

Vervolgens heb ik een JSON -bestand ingesteld met de configuratie in /etc/config.json met behulp van nano als volgt.

Om het bestand te bewerken:

sudo nano /etc/config.json
Voeg de volgende regels toe:

{ "E -mail_host_password": "" }

We zullen het configuratiebestand blijven bewerken en alle wachtwoorden en toetsen toevoegen die we in de app zullen gebruiken. Laten we voor nu snel onderzoeken hoe we e -mail kunnen verzenden met Python. Laten we eerst een sjabloon maken voor een verificatie -e -mail die we naar onze gebruikers kunnen verzenden en deze in de map Gebruikerssjablonen kunnen plaatsen. Deze sjabloon wordt geschreven in HTML.

nano -gebruikers/sjablonen/gebruikers/verificatie_email.html

Django -app - Controleer uw e -mail Beste {{user.UserName}}, Klik hier om uw e -mail te verifiëren. Als alternatief kunt u de volgende link in de adresbalk van uw browser plakken: {{base_url}} { % url 'gebruikers: activeer' uidb64 = uid token = token %} De link loopt binnen 30 minuten af. Als u geen verificatie -e -mail hebt gevraagd, kunt u deze e -mail gewoon negeren. Zie je daar, Madeliefje

Deze e -mail is vrij eenvoudig. Het neemt een context van een gebruiker, de basis -URL voor de site en een gebruikers -ID en token die worden gebruikt om de e -mail van de gebruiker te verifiëren. Zorg ervoor dat u de basis -URL in instellingen definieert.py voordat we wat Python -code schrijven om de sjabloon weer te geven. Ga je gang en voeg de volgende regels toe aan app/instellingen.py, nabij het begin.Site_Name = 'Django App' Protocol = 'https' Domein = 'example.com' Base_url = protocol + ': //' + domeinUiteindelijk, wanneer uw site klaar is voor internet en u deze implementeert, wilt u uw domein definiëren als de domeinnaam die u koopt om de site te vertegenwoordigen. Dit is de naam die u de NAVBAR typt om toegang te krijgen tot uw site. Voor nu kunt u het domein leeg laten of een tijdelijke aanduiding gebruiken. U wilt ook de site -naam wijzigen in een naam die u uw site wilt geven, naar keuze.

Voordat we e -mail verzenden, laten we een tokengenerator maken, zodat we een accountactiveringstoken kunnen hebben dat nooit verloopt. We kunnen dit doen door een accountactiveringstoken te bouwen en te importeren dat op het volgende lijkt. Bewerk het bestand:

nano -gebruikers/tokens.py

Voeg de volgende code toe:

van django.contrib.auth.tokens import wachtwoordresettokenGenerator importeren Importeer zes Klasse Tokengenerator (wachtwoordresettokenGenerator): def _make_hash_value (zelf, gebruiker, tijdstempel): opbrengst ( six.text_type (user.pk) + six.text_type (timestamp) )) Account_activering_token = tokengenerator () unsubscribe_token = tokengenerator ()

Deze basistokengenerator genereert een token dat we de gebruiker in een URL kunnen sturen en de gebruiker kan gebruiken om hun e -mail te verifiëren en hun account te activeren.
Laten we vervolgens kijken hoe u een e -mail kunt verzenden. Gebruik gebruikers/e -mail.py met behulp van nano.

nano -gebruikers/e -mail.py

Het verzenden van de verificatie HTML -e -mail ziet er zo uit:

Van django.contrib.auth import get_user_model van django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode van django.contrib.sites.shortcuts import get_current_site importeren Van django.core.mail importeren send_mail Van django.template.loader import render_to_string Van django.utils.encoding import force_bytes Van django.core.mail importeren e -mailmultialternatieven van django.shortcuts import render Van .Tokens Import Account_Activation_Token Van django.template.loader import render_to_string van django.utils.html import strip_tags Van django.template importsjabloon, context Van django.conf Importinstellingen Traceback importeren def send_verification_email (gebruiker): User = get_user_model () Mail_subject = '[{}] Activeer uw account.'. Format (settings.site_name) html_message = render_to_string ('gebruikers/verificatie_email.html', { 'Gebruiker': gebruiker, 'domein': settings.domain, 'protocol': 'https', 'uid': urlsafe_base64_encode (force_bytes (user.pk)), 'token': account_activation_token.make_token (gebruiker), }) send_html_email (gebruiker, mail_subject, html_message)

Dit is vrij eenvoudig. We importeren de functies die we nodig hebben om de e -mail te verzenden, de e -mail weer te geven met sjablonen en onze instellingen, en vervolgens definiëren we de e -mail met de sjabloonnaam en verzenden deze naar de gebruiker met behulp van een functie. U zult merken dat we de functie niet hebben gedefinieerd om de e -mail te verzenden, send_html_email, dus laten we dit hieronder schrijven hieronder de code die we al hebben toegevoegd aan gebruikers/e -mail.py
pip install django-crispy-forms
def send_html_email (gebruiker, mail_subject, html_message): to_email = user.email gebruikersnaam = user.gebruikersnaam if to_email == '': retourneer geen unsub_link = settings.base_url + user.profile.create_unsubscribe_link () html_message = html_message + "afmelden" msg = e-mailmultialternatieven (mail_subject, strip_tags (html_message), settings.default_from_email, [to_email], headers = {'list-unsubscribe': '<' + unsub_link + '>'},),),),) msg.attach_alternative (html_message, "text/html")) profiel = user.profile poging: msg.send (fail_silently = false) zo niet profiel.email_valid: profile.email_valid = true profile.Save () behalve: profile.email_valid = false profile.Save ()

Dit is een beetje complexer en we zijn nog niet klaar om al deze code uit te voeren. Merk op dat we een UNSUB_LINK definiëren, de link die de gebruiker kan gebruiken om zich af te melden bij onze e -mails. Dit is belangrijk, omdat gebruikers zich moeten kunnen afmelden voor onze e -mails, tenzij ze ze op elk moment willen zien. We voegen ook een tekstalternatief toe aan ons bericht, het HTML -bericht dat is ontdaan van HTML -tags. Ten slotte controleren we of de e -mail verzonden, en als dit niet het geval is, markeren we het profiel van de gebruiker dat hun e -mail niet geldig is.

Laten we teruggaan naar de gebruikersmodellen, zodat we dit allemaal kunnen laten werken. We moeten een functie definiëren om een ​​link naar afmelden te genereren en een Booleaans veld definiëren om te markeren dat de e -mail van de gebruiker niet geldig is.
    # Voeg eerst de volgende import toe bovenaan gebruikers/modellen.py
nano -gebruikers/modellen.py

#… Van django.core.signing Import TimestampSigner, Badsignature, SignatureExpired Van django.urls importeer omgekeerde omgekeerde

Laten we vervolgens functies toevoegen aan het gebruikersmodel om het token te maken en het token te controleren dat wordt gebruikt om de e -mail te activeren, evenals het veld om op te slaan of de gebruiker zijn e -mail met succes ontvangt. Voeg in gebruikers/modellen.py opnieuw de volgende code toe aan het einde van het model (ingesprongen code)

#… e -mail_valid = modellen.booleanfield (standaard = true) def make_token (self): Return TimestampSigner (). Sign (self.user.username) def check_token (zelf, token): poging: sleutel = '%s:%s'%(self.user.gebruikersnaam, token) TIMESTAMPSIGNER (). Unsign (sleutel, max_age = 60 * 60 * 24 * 30) # geldig gedurende 30 dagen behalve (BadSignature, SignatureExpired): Keer onwaar terug Return true def create_unsubscribe_link (self): gebruikersnaam, token = self.make_token (). split (":", 1) Return Reverse ('Users: UnsubSribe', Kwargs = {'gebruikersnaam': gebruikersnaam, 'token': token,})

Geldig voor 30 dagen

Dit is vrij eenvoudig, we gebruiken een tijdstempel, wat een basiscryptografietool is, om een ​​token te maken dat na een bepaalde tijd afloopt, en we gebruiken ook een andere functie om te controleren of deze geldig is. We gebruiken deze tokens twee keer, eenmaal om de e -mail te verifiëren, en eenmaal voor een afmeldlink.

Nu we deze hebben, is het laatste werk dat we moeten doen in de opvattingen. Laten we binnen gebruikers/views.py views toevoegen om het e -mailadres te verifiëren en om af te schrijven.

nano -gebruikers/views.py
python manage.py startapp users
Voeg eerst de volgende import toe. Ik heb er een paar extra in gegooid, dus we hoeven later niet meer items te importeren.

Van django.contrib.auth import uitloggen Van django.shortcuts importeren render, redirect, get_object_or_404 Van django.contrib.auth.models importeer gebruiker van django.utils.coding import force_str van django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode import JSON Verzoeken importeren DateTime importeren, traceback Van django.contrib Import berichten van .modellen importprofiel importeren van django.utils import timezone Van django.views.decorators.cache importeren nooit_cache Van .Email import send_verification_email # Zorg ervoor dat u de verzendende e -mail verzendfunctie importeert Van django.contrib.auth.decorators importeren login_required Van django.contrib.auth.mixins import LoginRequiredMixin, UserPassestestMixin Van django.utils.Decorators Import methode_decorator van django.http import httponseredirect Van django.conf Importinstellingen van django.utils import timezone DateTime importeren import pytz van django.views.decorators.csrf import csrf_exempt van django.http import httpResponse van django.contrib.auth.tokens import default_token_generator Van django.utils.http import urlsafe_base64_decode Van .Tokens Import Account_Activation_Token

Zorg ervoor dat u de verzendfunctie van de verificatie -e -mail importeert

Je hebt misschien al een aantal van deze import, maar het doet geen pijn om ze te herhalen. U moet onder andere de verzendende e -mail verzendfunctie importeren, evenals Account_Activation_Token van gebruikers.tokens, onder andere import.

Voeg nu, onderaan het bestand, de volgende code toe:

Def afmelding (verzoek, gebruikersnaam, token): user = get_object_or_404 (gebruiker, gebruikersnaam = gebruikersnaam) if ((request.user.is_authenticated en request.user == user) of user.profile.check_token (token)): # meld ze af profiel = user.profile Profiel.subscribed = false profile.Save () Return Render (Request, 'Users/UnsubSribe.html')) # Anders doorverwijs naar de inlogpagina berichten.warning (aanvraag, f'your afmelden is verlopen. Log in om af te melden. ') next_url = reverse ('Users: UnsubSribe', Kwargs = {'gebruikersnaam': gebruikersnaam, 'token': token,}) Retourneer HTTPRESPONSEREDIRECT ('%s? Next =%s'%(reverse ('login'), next_url))) def activeren (verzoek, UIDB64, token): poging: uid = force_str (urlsafe_base64_decode (uidb64))) user = user.objects.get (pk = uid) Behalve (TypeError, ValueError, OverflowerRor, User.DoeSnotexist): Gebruiker = geen ip = get_client_ip (verzoek) Als de gebruiker niet geen en account_activatie_token.check_token (gebruiker, token) is: user.profile.email_verified = true User.Profile.Save () User.Save () # SendWelcomeMail (verzoek, gebruiker) berichten.success (verzoek, f'thanks voor het bevestigen van uw e -mail! U kunt nu inloggen op uw account, en er is een welkome e -mail naar u verzonden. ') return redirect (user.profile.create_face_url ()) anders: berichten.success (verzoek, f'your activerings link is verlopen. Vraag een nieuwe activeringslink aan. ') return Redirect ('verifieer: verifie') def resend_activatie (verzoek): if request.method == 'post': Form = ResendActiveryMailform (Request.Post) e -mail = request.post ['e -mail'] poging: user = user.objects.get (e -mail = e -mail) send_verification_email (gebruiker) berichten.success (verzoek, 'uw verificatie -e -mail verzonden. Klik op de link in uw e -mail om uw account te verifiëren.') Return Redirect (reverse ('verifieer: verifie')) behalve: berichten. Waren (verzoek, f'your -e -mail is niet correct. Probeer het opnieuw. ') anders: Form = ResendActiveryMailform () Return Render (Request, 'Users/Resend_Activation.Html', {'Form': Form, 'Title': 'Resend Activation', 'Small': True})

mafschrijven ze
        username = request.POST['username'] # Anders verleid de inlogpagina
        password = request.POST['password'] # SendWelcomeMail (verzoek, gebruiker)
Dit is veel code. Laten we het afbreken. De eerste functie, schoon en eenvoudig, maft de gebruiker af van de mailinglijst. De tweede functie activeert hun e -mail en u zult merken dat ik een becommentareerde functie, SendWelcomeMail heb toegevoegd. U bent van harte welkom om een ​​e -mailsjabloon en functiedefinitie te gebruiken om een ​​welkome e -mail te verzenden, dat heb ik gewoon nog niet gedaan. De laatste functie waarin ik heb gooide is belangrijk, omdat activerings -e -mails vervallen. Daarom moeten we de activeringsmail enig van de tijd opnieuw verzenden. We kunnen hiervoor een basisformulier gebruiken en de functie aanroepen om de verificatie -e -mail te verzenden. Voordat we dit doen, laten we ervoor zorgen dat het in de eerste plaats wordt verzonden, door een functieaanroep toe te voegen aan de registerweergave. Voeg deze regel toe vlak voor de omleiding in de registerweergave, def register, in gebruikers/views.py.

nano -gebruikers/views.py

#… (Na) def register (verzoek): send_verification_email (gebruiker) #… (Eerder) Redirect (
mkdir users/templates
mkdir users/templates/users
… (Na) def register (verzoek):

… (Eerder) omleiden (

U hoeft de eerste en laatste regels niet toe te voegen in dat codefragment, zorg ervoor dat de registerweergave de verificatie -e -mail naar de gebruiker verzendt. Het zou er zo uit moeten zien:
nano users/templates/users/login.html
# ... importeert Van .forms importeer userRegisterForm def register (verzoek): if request.method == "post": Form = UserRegisterForm (Request.Post) if form.is_valid (): user = form.SAVE () Send_verification_email (gebruiker) # Zorg ervoor dat u deze regel toevoegt! messages.success (verzoek, 'Welkom bij de app, {}.'. Format (user.UserName))) Return Render (Request, 'Users/Register.html', {'Form': UserRegisterForm}))

… Importeren

Zorg ervoor dat u deze regel toevoegt!
Nu moeten we een formulier toevoegen om de activerings -e -mail te verzenden. Voeg in gebruikers/forms.py het volgende formulier toe:

# ... (importeert) Class ResendActiveryMailform (Forms. e -mail = formulieren. Emailfield (vereist = true)

… (Imports)
We hebben ook een sjabloon nodig die overeenkomt met dit verzonden e -mailactiveringsformulier. Laten we deze sjabloon toevoegen. Bewerk het bestand:

nano -gebruikers/sjablonen/gebruikers/resend_activation.html

Voeg vervolgens de volgende code toe aan het bestand.
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm

class UserRegisterForm(UserCreationForm):
    email = forms.EmailField()

    class Meta:
        model = User
        fields = ['username', 'email', 'password1', 'password2']
{ % verlengt 'base.html' %} { % blokinhoud %} { % laden Crispy_forms_tags %} { % csrf_token %} Stuur activerings -e -mail opnieuw {{Form | Crispy}} Stuur activerings -e -mail opnieuw { % endblock %}

Oef, dat is veel! Wanneer we de code op onze server implementeren, kunnen we HTML -e -mail verzenden en gebruikersaccounts activeren met een klik in de e -mail. We willen misschien ook een eenvoudige welkome e -mail verzenden, dus laten we eens kijken hoe we dat moeten doen. Terug in gebruikers/e -mail.py, voeg de volgende code toe:

def sendWelcomeMail (gebruiker): User = get_user_model () html = open ('{}/users/Welcome_email.html'.Format (settings.base_dir)). Read () subject = 'Welcome to' + Settings.Site_Name + ', {{gebruikersnaam}}!' sjabloon = sjabloon (html) subjtemplate = sjabloon (onderwerp) context = context ({'gebruikersnaam': user.username, 'base_url': settings.base_url, 'Model_Name': 'Daisy Holton,' Site_name ': settings.site_name})) RenderedTemplate = sjabloon.render (context) subjContext = context ({'gebruikersnaam': user.UserName})) SubjrenderedTemplate = subjtemplate.render (subjContext) send_html_email (gebruiker, subjRenderedTemplate, rderedTemplate)

Ook hebben we een sjabloon nodig om al deze informatie weer te geven. Op mijn website ziet de sjabloon eruit als hieronder, maar u bent van harte welkom om het te formatteren zoals u leuk vindt.

Welkom bij {{site_name}} Hallo {{gebruikersnaam}}, We zijn blij je hier te zien! Bedankt voor het toetreden tot {{Site_name}} en deel uitmaken van het plezier. Om aan de slag te gaan, zijn hier een paar dingen die u kunt doen nadat u uw identiteit hebt verifieerd. Gebruik de app. Dit is de hoofdpagina van {{Site_name}} Bezoek mijn privé {{site_name}} profiel. Dit is een pagina voor iedereen die me wil leren kennen. Meer profielen. U kunt deze mensen op de site vinden en hun inhoud zien. Bekijk hier alle berichten. Dit is de privé -voorpagina van {{Site_name}}. Er is nog meer op de site, dus voel je vrij om te bezoeken en te zien wat je vindt. U kunt de site delen met een van de sociale knoppen op elke pagina. Ik hoop dat je geniet van je tijd met {{site_name}}! Bedankt dat je hier bent. Met veel liefde, {{Model_name}} {{base_url}}
# Merk op dat we geen sluitende body- of HTML -tags hebben, omdat we deze toevoegen wanneer we de HTML -afmelding -link toevoegen. Deze zijn belangrijk, maar we willen ze niet twee keer definiëren.
Dus wat is het volgende? We hebben een lange weg afgelegd. We moeten echt klaar zijn om de site op een server te implementeren. We kunnen de @Login_Required Decorator toevoegen en onze weergaven beveiligen, gebruikersaanmeldingen nemen, conforme e -mail en cache -informatie verzenden, die de basis vormt van wat een website moet doen om relevant te blijven. We voegen een paar meer nuttige functies toe en bouwen vervolgens een basis voor het implementeren van onze code op een externe server, het instellen van een e -mailserver, domeinconfiguratie en filters om onze site veilig en geschikt te maken.

We hebben ook een weergave -weergave nodig, dus laten we dat heel snel toevoegen. Django's ingebouwde wachtwoordresetweergave is verbroken in sommige functies, maar we zullen kijken hoe we onze eigen weergave, e -mailsjabloon, formulieren en URL -patronen kunnen schrijven. Dit is hoe de weergave eruit ziet, in gebruikers/views.py

#... importeert van django.contrib.auth.tokens import default_token_generator van django.contrib.auth.forms import setPasswordform import Van django.utils.http import urlsafe_base64_decode def wachtwoord_reset (verzoek, uidb64, token): user = get_object_or_404 (gebruiker, id = urlsafe_base64_decode (uidb64))) if request.method == 'post': Form = setPassWordForm (gebruiker, request.Post) if form.is_valid () en default_token_generator.check_token (gebruiker, token): Form.Save () berichten.success (verzoek, 'Uw wachtwoord is gereset.') Elif Not Form.is_valid (): berichten Return Redirect (Request.Path) anders: berichten.warning (verzoek: 'Uw linksreset -link is verlopen. Maak een nieuwe.') Return Redirect (Reverse ('Users: Login')) Retourneer render (verzoek, 'gebruikers/wachtwoord_reset_confirm.html', { 'Titel': 'Reset uw wachtwoord', 'Form': setPassWordForm (gebruiker)
from django.db import models # ... Importeren
    author = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True, related_name='posts') # Dit formulier is ingebouwd in Django, maar we hebben een sjabloon nodig om de wachtwoordreset te bevestigen, gebruikers/sjablonen/gebruikers/wachtwoord_reset_confirm.html
{ % verlengt 'base.html' %} { % laden Crispy_forms_tags %} { % blokinhoud %} { % csrf_token %} Reset wachtwoord {{Form | Crispy}} Reset wachtwoord { % Endblock -inhoud %}

We hebben ook een sjabloon om een ​​wachtwoordreset -e -mail te verzenden, met een eenvoudig formulier, in gebruikers/sjablonen/gebruikers/wachtwoord_reset.html

{ % verlengt 'base.html' %} { % laden Crispy_forms_tags %} { % blokinhoud %} { % csrf_token %} Reset wachtwoord {{Form | Crispy}} Vraag het wachtwoord opnieuw in { % Endblock -inhoud %}

De sjabloon voor de e -mail zelf is eenvoudig, het is een basis HTML -bestand dat een link weergeeft om het wachtwoord te resetten, in gebruikers/sjablonen/gebruikers/wachtwoord_reset_email.html. Django zal dit bestand automatisch interpreteren.

Uglek - Reset uw wachtwoord Hallo, Klik hier om uw wachtwoord te resetten. Als alternatief kunt u de volgende link in uw browser plakken: https://uglek.com { % url 'wachtwoord_reset_confirm' uidb64 = uid token = token %} Als u geen wachtwoordreset hebt gevraagd, kunt u deze e -mail gewoon negeren. Bedankt voor het bij ons, Madeliefje
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True, related_name='profile')
    account_created = models.DateTimeField(default=timezone.now)
    last_seen = models.DateTimeField(default=timezone.now)
    can_login = models.DateTimeField(default=timezone.now)
    preferred_name = models.CharField(max_length=20,default='', null=True, blank=True)
    bio = models.TextField(blank=True, default='')
We hebben ook nog twee sjablonen nodig. De eerste is om te bevestigen dat de e -mail is verzonden. Weergaven hiervoor zijn al in Django, dus we moeten ze gewoon aanspreken in de urls.py. Deze sjabloon bevindt zich bij gebruikers/sjablonen/gebruikers/wachtwoord_reset_done.html

{ % verlengt 'base.html' %} { % blokinhoud %} Er is een e -mail verzonden met instructies om uw wachtwoord te resetten. { % Endblock -inhoud %}

En ten slotte, om te bevestigen dat de wachtwoordreset is voltooid, is gebruikers/sjablonen/gebruikers/wachtwoord_reset_complete.html

{ % verlengt 'base.html' %} { % blokinhoud %} Uw wachtwoord is ingesteld. Log hier in { % Endblock -inhoud %}

Nu hebben we URL -patronen nodig voor deze weergaven. Voeg bij gebruikers/urls.py de volgende URL -patronen toe:
# urlpatterns = [
    #... eerdere URL's hier
    pad ('wachtwoord-reset/',
         auth_views.passwordresetview.as_view (
             template_name = 'gebruikers/wachtwoord_reset.html',
             html_email_template_name = 'gebruikers/wachtwoord_reset_html_email.html'
         ),
         name = 'wachtwoord_reset'),
    pad ('wachtwoord-reset/klaar/',
         auth_views.passwordresetdoneview.as_view (
             sjabloon_name = 'gebruikers/wachtwoord_reset_done.html'
         ),
         name = 'wachtwoord_reset_done'),
    pad ('wachtwoord-reset-confirm ////',
         auth_views.PasswordResetConfirmview.as_view (
             template_name = 'Users/wachtwoord_reset_confirm.html'
         ),
         name = 'wachtwoord_reset_confirm'),
    pad ('wachtwoord-reset-complete/',
         auth_views.PasswordResetCompleteView.as_view (
             template_name = 'gebruikers/wachtwoord_reset_complete.html'
         ),
         name = 'wachtwoord_reset_complete'),
]
            Profile.objects.create(user=user) # ... eerdere URL's hier
Vier sjablonen, dat is veel! Maar nu kunnen we zeker zijn om het wachtwoord van de gebruiker te resetten wanneer we moeten, allemaal vanuit de webbrowser.

Ik begrijp dat dit veel code is. Als het een beetje over je hoofd lijkt, is dat oké. Je zult verbeteren, je begrip zal verbeteren en je zult snel veel competenter worden met code. Als je helemaal verloren bent, raad ik aan om later terug te keren naar deze software na te hebben gewerkt aan een zelf-leren om online te coderen. Deze zijn meestal gratis om aan de slag te gaan en zullen je door alles begeleiden wat je nodig hebt om succesvol te zijn wanneer je terugkomt naar dit project. Als u het gevoel hebt dat u klaar bent om door te gaan, verder te lezen, dan zullen we de implementatie van uw code naar een externe server behandelen en een e -mailserver instellen, evenals het automatiseren van uw implementatie met behulp van BASH, zodat u altijd een nieuw project kunt instellen met een paar eenvoudige opdrachten.

Het laatste wat we moeten doen voordat we naar een externe server worden geïmplementeerd, is onze site een beetje veiliger maken. U zult merken dat de inlogweergave alleen een gebruikersnaam en wachtwoord nodig heeft, en er is geen multi -factor authenticatie of eenmalige code. Dit is een eenvoudige oplossing en met dezelfde code kunnen we onze site sms -berichten laten verzenden en zelfs reageren op sms -berichten die naar de server zijn verzonden. Om te beginnen gaan we terug naar de gebruikersmodellen en voegen we een tijdstempel -ondertekenaar toe die elke login vertegenwoordigt. We zullen ook een unieke, roterende ID toevoegen aan het gebruikersmodel dat zal worden gebruikt om extra beveiliging aan onze login toe te voegen. De gebruikersmodellen bewerken, gebruikers/modellen.py, voeg de volgende code toe:
# van django.db importmodellen
Van django.contrib.auth.models importeer gebruiker
van django.utils import timezone
# Zorg ervoor dat u de UUID, Timestamp Signer en URL -generator importeert (Reverse)
import uuid
Van django.core.signing Import TimestampSigner, Badsignature, SignatureExpired
Van django.urls importeer omgekeerde omgekeerde

Klasse profiel (modellen.model):
    user = modellen.onetoOnefield (gebruiker, on_delete = modellen.cascade, null = true, blank = true, gerelateerd_name = 'profiel')
    Account_created = modellen.datetimeField (standaard = timeZone.now)
    last_seen = modellen.datetimeField (standaard = timeZone.now)
    can_login = modellen.datetimeField (standaard = timeZone.now)
    preferred_name = modellen.charfield (max_length = 20, default = '', null = true, blank = true)
    bio = modellen.TextField (blank = true, default = '')
    # Voeg deze code hier toe
    uid = modellen.charfield (max_length = 32, default = uuid.uuid4, null = true, blank = true)
    mfa_enabled = modellen.booleanfield (standaard = false)
    enable_mfa = modellen.booleanfield (standaard = false)
    Phone_Number = modellen.charfield (standaard = '', null = true, blank = true, max_length = 15)
    verificatie_code = modellen.charfield (default = '', null = true, blank = true, max_length = 15)
    verificatie_code_length = modellen.integerfield (standaard = 6)
    MFA_CODE_EXPIRES = modellen.datetimeField (standaard = timeZone.now)
    mfa_attempts = modellen.integerfield (standaard = 0)

    def make_auth_token (self):
        Return TimestampSigner (). Sign (self.uid)

    # En voeg deze functie toe
    def create_auth_url (self):
        gebruikersnaam, token = self.make_auth_token (). split (":", 1)
        Return Reverse ('Users: MFA', Kwargs = {'gebruikersnaam': gebruikersnaam, 'token': token,})

    def check_auth_token (zelf, token):
        poging:
            sleutel = '%s:%s'%(self.uid, token)
            TIMESTAMPSIGNER (). Unsign (toets, max_age = 60 * instellingen.auth_valid_minutes) # Geldig voor 3 minuten
        behalve (BadSignature, SignatureExpired):
            Keer onwaar terug
        Return true
        if user and user.profile.can_login < timezone.now(): # Zorg ervoor dat u de UUID, Timestamp Signer en URL -generator (achteruit) importeert
        else: # Voeg deze code hier toe
            user = User.objects.filter(username=username).first() # En voeg deze functie toe
                profile.can_login = timezone.now() + datetime.timedelta(seconds=15) # Geldig voor 3 minuten
Zorg ervoor dat uw gebruikers/modellen.py er zo uitziet, naast de reacties (code op de regels met #). Dit afbreken, het is eenvoudig. We hebben een paar import, een tijdstempel, een cryptografisch hulpprogramma dat een veilige code kan genereren en deze kan verifiëren om ervoor te zorgen dat het geldig is, slechts eenmaal wordt gebruikt en niet ouder dan een bepaald aantal seconden. We gebruiken ook een UUID, een unieke identificatie die onze gebruiker identificeert bij het ondertekenen van het token, en in de URL waar het token naar de gebruiker wordt verzonden. We zullen deze basiscryptografie gebruiken om een ​​weerweergave met twee factoren authenticatie te bouwen. Voordat we iets anders doen, laten we de migraties uitvoeren, zodat onze gebruikersmodellen worden bijgewerkt. Voer in de map met management.py de volgende opdrachten uit om de migraties te maken en te voltooien.

Bron venv/bin/activeren python manag.py makemigrations && python manag.py migrate

Dit is belangrijk omdat elke keer dat we wijzigingen aanbrengen in de modellen, we de tabellen moeten maken en de database moeten bijwerken met standaardwaarden voordat we de modellen daadwerkelijk kunnen gebruiken.

Laten we vervolgens onze inlogweergave improviseren om een ​​secundaire authenticatieweergave om te leiden. Verwijder in gebruikers/views.py de inlogfunctie en leid naar de URL die we zojuist hebben gegenereerd in de gebruikersmodellen.

# ... importeert def -login (verzoek): if request.method == "post": gebruikersnaam = request.Post ['gebruikersnaam'] wachtwoord = request.Post ['wachtwoord'] user = authenticate (gebruikersnaam = gebruikersnaam, wachtwoord = wachtwoord) Als user en user.profile.can_login <timeZone.now (): # Merk op dat we nu controleren of de gebruiker inlogt # Verwijder de Auth_Login -functie die hier was berichten.success (verzoek: 'Uw wachtwoord is geaccepteerd. Ga verder.') if user.profile.mfa_enabled: return Redirect (user.profile.create_auth_url ()) # Opmerking We leiden hier door naar een nieuwe URL Anders: # Als de gebruiker Mutli-factor authenticatie niet gebruikt, log ze dan gewoon in. auth_login (verzoek, gebruiker, backend = 'django.contrib.auth.backends.modelbackend')) Return Redirect ('Feed: Feed') anders: # als de login niet succesvol was, berichten.warning (verzoek, 'gebruikersnaam of wachtwoord onjuist. Probeer het opnieuw.') user = user.objects.filter (gebruikersnaam = gebruikersnaam) .first () # Dit is het deel waar we het gebruikersprofiel bijwerken Als gebruiker: profiel = user.profile profile.can_login = timezone.now () + datetime.timedelta (seconden = 15) # zodat ze niet opnieuw kunnen inloggen voor een paar seconden profile.Save () Return Render (Request, 'Users/Login.html', {'Form': AuthenticationForm ()})
sudo backup
… Importeren

Merk op dat we nu controleren of de gebruiker kan inloggen

Verwijder de Auth_Login -functie die hier was
sudo crontab -e
Let op dat we hier doorgaan naar een nieuwe URL

Als de gebruiker multi-factor authenticatie niet gebruikt, logt u ze gewoon in.

Als de login niet succesvol was,
0 * * * * sudo backup
Dit is het deel waar we het gebruikersprofiel bijwerken

Dus ze kunnen niet opnieuw inloggen voor een paar seconden

Dus dit is vrij eenvoudig, we hebben nu een manier om de Two Factor -verificatieweergave om te leiden wanneer we deze maken. We hebben ook een fallback voor het geval de gebruiker geen telefoonnummer heeft toegevoegd. We zullen een basisweergave toevoegen om binnenkort een telefoonnummer toe te voegen en binnenkort in te loggen met een sms -bericht.

Eerst hebben we een eenvoudige manier nodig om een ​​sms -bericht van onze code te verzenden. Om dit te doen, kunnen we kiezen uit een aantal API's, maar de gemakkelijkste is naar mijn mening Twilio. Ze bieden ook goede prijzen voor kleinere projecten, evenals bulkkortingen. Maak een account aan op twilio.com, vul enkele details over uw project in, koop een telefoonnummer en kopieer uw API -toetsen naar uw instellingen.py. Voeg vervolgens deze code toe onder een nieuw bestand, gebruikers/sms.py.

nano -gebruikers/sms.py
sudo visudo
# Importeer alle benodigde pakketten van django.utils import timezone willekeurig importeren DateTime importeren Van django.conf Importinstellingen van feed.middleware import get_current_request Van django.contrib Import berichten Traceback importeren account_sid = settings.twilio_account_sid auth_token = settings.twilio_auth_token source_phone = instellingen.phone_nummer # Deze code verzendt de tekst met Twilio def send_text (target_phone, tekst): van Twilio.rest import client poging: client = client (account_sid, auth_token) Als len (target_phone)> = 11: message = client.Messages.Create ( tot = target_phone, from_ = source_phone, body = tekst) behalve: print (traceback.format_exc ()) # Een helperfunctie om een ​​nummer te krijgen met zoveel cijfers def get_num_length (num, lengte): n = '' voor X in bereik (lengte): n = n + str (num) Return int (n) # Stuur de tekst om de gebruiker te verifiëren def send_verification_text (gebruiker): lengte = user.profile.verification_code_length code = random.randint (get_num_length (1, lengte), get_num_length (9, lengte)); user.profile.verification_code = code user.profile.mfa_code_expires = timezone.now () + datetime.timedelta (minuten = 3) User.Profile.Save () send_user_text (gebruiker, "Uw verificatiecode voor {} is {}". Format (settings.site_name, str (code)))) # Stuur een gebruiker elke tekst met deze functie def send_user_text (gebruiker, tekst): send_text (user.profile.phone_nummer, tekst) # Valideer de code met deze functie def check_verification_code (gebruiker, code): user.profile.mfa_attempts += 1 result = user.profile.verification_code! = Geen en code! = '' en user.profile.verification_code == code en user.profile.mfa_code_expires> timezone.now () en user.profile.mfa_attempts <= 3 if user.profile.mfa_attempts <3 en resultaat: user.profile.verification_code_length = 6 elif user.profile.mfa_attempts> 2 en geen resultaat: user.profile.verification_code_length = 8 User.Profile.Save () Retourresultaat # Valideer de tijd def check_verification_time (gebruiker): result = user.profile.mfa_code_expires> timezone.now () Retourresultaat

Importeer alle benodigde pakketten

Deze code verzendt de tekst met Twilio
ALL ALL=NOPASSWD: /bin/backup
Een helperfunctie om een ​​nummer te krijgen met zoveel cijfers

Stuur de tekst om de gebruiker te verifiëren

Stuur een gebruiker elke tekst met deze functie

Valideer de code met deze functie

Valideer de tijd

Zorg ervoor dat u uw instellingen op de juiste manier wijzigt en deze regels toevoegt met uw sleutels:

# Zorg ervoor dat u deze kopieert van uw Twilio Dashboard Twilio_account_sid = "" Twilio_auth_token = "" Telefoon_nummer = "" Site_Name = "" Auth_valid_minutes = 3 # het aantal minuten dat de TFA -pagina actief is zodra is geïnstantieerd

Zorg ervoor dat u deze van uw Twilio Dashboard kopieert

Het aantal minuten dat de TFA -pagina actief is, is eenmaal geïnstalleerd

Ten eerste hebben we formulieren nodig voor onze twee factor authenticatieweergaven. Gebruikers/formulier.py bewerken, voeg de volgende code toe.

# ... importeert van Django Import Forms # Een formulier voor het invoeren van ons telefoonnummer Class PhonenumberForm (Forms. Phone_Number = Forms.Regexfield (regex = r '^\+? 1? \ d {9,15} $', error_messages = {'invalid': "Telefoonnummer moet worden ingevoerd in het formaat: '+9999999999'. Tot 15 cijfers is toegestaan."}) def __init __ (zelf, *args, ** Kwargs): super (phonenumberform, self) .__ init __ (*args, ** kwargs) self.fields ['phone_number']. label = phone_number_label # Een formulier voor authenticeren Class TfAform (Forms. code = forms.integerfield (vereist = false) def __init __ (zelf, *args, ** Kwargs): super (tfaform, self) .__ init __ (*args, ** kwargs) self.fields ['code']. widget.attrs.update ({'autocomplete': 'off'}) help_texts = { 'Code': 'Voer de zescijferige code in nadat u deze naar uw telefoon hebt verzonden met de knop hierboven.' }
nano app/settings.py
… Importeren

Een formulier voor het invoeren van ons telefoonnummer

Een formulier voor authenticeren

Laten we vervolgens de weergaven maken in gebruikers/views.py

# ... importeert van django.http import httponseredirect van .forms import phoneNumberForm, tfaForm def mfa (verzoek, gebruikersnaam, token): user = user.Objects.filter (profile__UUID = gebruikersnaam) .first () zo niet de gebruiker: retourneer httpResponseredirect (reverse ('verifieer: leeftijd') + '? next =' + request.get.get ('volgende') if request.get.get ('next') else '/go/' if request.user.is_authenticated en request.user.Profile.Vendor else '/' if request.user.is_authenticeer anders reverse ('gebruikers) user = get_object_or_404 (gebruiker, profile__UUID = gebruikersnaam) next = request.get.get ('next', '') zo niet gebruiker.profile.mfa_enabled: zo niet check_verification_time (gebruiker): user.profile.mfa_enabled = false user.profile.enable_two_factor_authentication = true user.profile.phone_number = '+1' User.Profile.Save () print ('inloggen gebruiker') auth_login (verzoek, gebruiker, backend = 'django.contrib.auth.backends.modelbackend')) berichten.warning (verzoek: 'Voer een geldig telefoonnummer in en verifieer het met een code.') Return Redirect (reverse ('gebruikers: mfa_onboarding'))) if request.method == 'post': Form = Tfaform (request.Post) code = form.data ['code'] Als code en code! = '' en code! = Geen: token_validated = user.profile.check_auth_token (token) p = user.profile is_verified = check_verification_code (gebruiker, int (code)) p.mfa_authenticated = is_verified Als token_validated: If is_verified: user.profile.mfa_enabled = true User.Profile.Save () auth_login (verzoek, gebruiker, backend = 'django.contrib.auth.backends.modelbackend')) P.verfication_code = geen p.uid = get_uuid () P.Save () berichten.success (verzoek: 'U bent geverifieerd. Welkom.') QS = '?' Voor de sleutel, waarde in request.get.items (): qs = qs + key + '=' + waarde + '&' Als volgende! = '' en niet (next.startswith ('/Accounts/Logout/') of Next.StartSwith ('/Accounts/Login/') of Next.StartSwith ('/admin/login/') of Next.StartsWith ('/Accounts/Register/')): retourneer httpResponseredirect (ext) elif next.startswith ('/accounts/logout/') of next.startswith ('/accounts/login/') of next.startswith ('/Accounts/register/'): Return Redirect ('Feed: Feed') elif request.meta.get ('http_referer', '/').startswith('/accounts/login/'): Return Redirect (Reverse ('Feed: Feed')) Elif niet de volgende: Return Redirect (Reverse ('Feed: Feed') anders: Return httpResponseredirect ('feed: feed') anders: berichten.warning (verzoek: 'De code die u hebt ingevoerd, is niet herkend. Probeer het opnieuw.') elif niet token_validated: berichten. Waren (verzoek, 'het URL -token is verlopen of is niet herkend. Probeer het opnieuw.' uitloggen (verzoek) Return Redirect (Reverse ('Users: Login')) Als p.mfa_attempts> 3: berichten.warning (verzoek: 'U hebt de onjuiste code meer dan 3 keer ingevoerd. Stuur uzelf een nieuwe code.') P.Verification_Code = geen P.Save () elif user.profile.can_send_mfa <timeZone.now (): user.profile.mfa_attempts = 0 user.profile.can_send_mfa = timezone.now () + datetime.timedelta (minuten = 2) User.Profile.Save () send_verification_text (gebruiker) berichten.success (verzoek: "Voer de code in die naar uw telefoonnummer is verzonden. De code verloopt binnen 3 minuten.") anders: berichten Form = tfaform () hide_logo = geen if user.profile.hide_logo: hide_logo = true Return Render (Request, 'Users/Mfa.html', {'title': 'Enter Code', 'Form': Form, 'XSMall': True, 'User': User, 'Hide_Logo': Hide_Logo, 'Accl_Logout': User.Profile.Shake_to_to_to_to_to_Logout, 'PRELOAD': FALSE})) @login_required def mfa_onboarding (verzoek): if request.method == 'post': Form = PhonenumberForm (Request.Post) request.user.profile.phone_number = form.data ['Phone_Number']. Vervang ('-', '') .Replace ('(', ''). Vervang (')', '') request.user.profile.mfa_enabled = true request.user.profile.enable_two_factor_authentication = true request.user.profile.save () berichten.success (verzoek: 'U hebt een telefoonnummer aan uw account toegevoegd.') gebruiker = request.user return redirect (user.profile.create_auth_url ())Form = phonenumberform (initial = {'phone_number': request.user.profile.phone_number if request.user.profile.phone_number else '+1'}) Return Render (Request, 'Users/MFA_ONBoarding.Html', {'Title': 'Voer uw telefoonnummer in,' Form ': Form,' Small ':
SITE_NAME = 'Django App'

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'localhost'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_ADDRESS = username@server.com'
EMAIL_HOST_USER = 'username'
EMAIL_HOST_PASSWORD = config['EMAIL_HOST_PASSWORD']
DEFAULT_FROM_EMAIL = '{} <{}>'.format(SITE_NAME, EMAIL_HOST_USER)
… Importeren

We hebben ook sjablonen nodig voor beide opvattingen. Laten we eerst de MFA -sjabloon toevoegen.

nano -gebruikers/sjablonen/gebruikers/mfa.html
import os
import json
with open('/etc/config.json') as config_file:
    config = json.load(config_file)
Voeg deze HTML -code toe aan de sjabloon

{ % verlengt 'base.html' %} { % blokinhoud %} { % load app_filters %} { % laden Crispy_forms_tags %} { % csrf_token %} Voer de verificatiecode in Stap 1: Stuur de code Deel nooit uw code met iemand, omdat deze kan worden gebruikt om tijdelijk toegang te krijgen tot uw account. Stuur code Stap 2: Voer de code in {{Form | Crispy}} Druk op de knop ENTER om uzelf de code te verzenden op {{user.profile.phone_number | SecurePhone}}. Voer vervolgens de code in en druk op Enter. Voer code in { % endblock %}

Dit is behoorlijk zelfverklarend. Het formulier verzendt een code of een lege code en u merkt in de weergave in de weergave die we de code verzenden als we een lege code ontvangen. Dan hebben we slechts twee verzendknoppen, en op deze manier kunnen we de code met beide knop verzenden. Vervolgens voegen we een eenvoudig formulier toe om een ​​telefoonnummer toe te voegen.

nano -gebruikers/sjablonen/gebruikers/mfa_onboarding.html

Voeg de volgende HTML toe:
sudo nano /etc/config.json
{ % verlengt 'base.html' %} { % blokinhoud %} { % laden Crispy_forms_tags %} { % csrf_token %} Stel twee factor authenticatie in {{Form | Crispy}} Telefoonnummer toevoegen { % endblock %}

Dit formulier is een stuk eenvoudiger, het maakt gewoon het telefoonnummerformulier dat we hebben gemaakt en laat de gebruiker een telefoonnummer toevoegen.

Dit ziet er echt goed uit! Zolang alles goed is ingesteld, moeten we berichten kunnen verzenden en de gebruiker inloggen met hun telefoonnummer zodra we de URL -patronen toevoegen. Het laatste wat we moeten instellen is een profielweergave, zodat we ervoor kunnen zorgen dat de gebruiker zijn telefoonnummer kan wijzigen zonder in te loggen. Ook zullen we uiteindelijk een optie "Stop To Quit" toevoegen, zodat de gebruiker "Stop" kan sms'en voor toekomstige tekstberichten.
{
	"EMAIL_HOST_PASSWORD": "<some password here>"
}
Laten we een profielweergave toevoegen aan de gebruikers/views.py. Deze weergave zal de bio, e -mail, gebruikersnaam en telefoonnummer van de gebruiker bijwerken en ons in staat stellen om multi -factor authenticatie mogelijk te maken. Ten eerste hebben we nog twee formulieren nodig in gebruikers/vormen. Py

#... importeert Class UserUpdateForm (Forms.Modelform): E -mail = formulieren. Emailfield () Class Meta: model = gebruiker fields = ['gebruikersnaam', 'e -mail'] Phone_Number_Label = 'Telefoonnummer (geen spaties, haakjes \' (\ 'of streepjes \'-\ ', nummers beginnend met + alleen)' Class ProfileUpDateForm (Forms.Modelform): geabonneerd = formulieren. Booleanfield (vereist = false) phone_number = forms.charfield (vereist = false) def __init __ (zelf, *args, ** Kwargs): super (ProfileUpDateForm, self) .__ init __ (*args, ** Kwargs) Class Meta: model = profiel fields = ['bio', 'phone_number', 'enable_mfa', 'geabonneerd']

... Importeren
nano users/templates/users/verification_email.html
Vervolgens kunnen we een weergave maken om beide vormen te gebruiken. Gebruikers/views.py bewerken en de weergave toevoegen.
# Voeg deze import toe Van .Forms importeer userUpDateForm, profileUpDateForm Van django.views.decorators.cache importeren nooit_cache van django.views.decorators.csrf import csrf_exempt van .modellen importprofiel importeren van .mfa import send_user_text @CSRF_ Exempt @Never_Cache @login_required def profiel (verzoek): if request.method == 'post': u_form = userUpDateForm (request.Post, instance = request.user) p_form = profileUpDateForm (request.Post, Request.Files, instantie = request.user.profile) if u_form.is_valid () en p_form.is_valid (): new_phone_number = p_form.data ['Phone_Number'] u_form.save () profile = p_form.save (commit = false) profile.phone_number = profile.phone_number.replace ('-', '') .Replace ('(', ''). vervang (')', '') profile.Save () Als new_phone_number! = oldprofile.phone_nummer en oldprofile.phone_number en len (oldprofile.phone_number)> = 11: profile.mfa_enabled = true profile.Save () send_text (oldprofile.phone_number, 'Uw telefoonnummer is bijgewerkt naar' + new_phone_number + '. Raadpleeg tekst op die telefoon om in te loggen. Als u deze wijziging niet hebt aangebracht, belt u ons. - {}'. Formaat (settings.site_name))) Als profiel.enable_two_factor_authentication en profile.phone_number en len (profile.phone_number) <11: profile.enable_two_factor_authentication = false berichten.success (verzoek, f'two factor authenticatie kan worden geactiveerd zonder een telefoonnummer in te voeren. Voer een telefoonnummer in om twee factorauthenticatie mogelijk te maken. ') profile.Save () Als new_phone_number! = oldprofile.phone_number en new_phone_number en len (new_phone_nummer)> = 11: send_user_text (request.user, 'U hebt dit nummer toegevoegd aan {} voor twee factorauthenticatie. U kunt nu uw nummer gebruiken voor twee factorauthenticatie. Als u deze wijziging niet hebt aangebracht, belt u ons. - {}'. Formaat (settings.site_name, settings.domein)))) profile.mfa_enabled = true profile.mfa_code_expires = timezone.now () + datetime.timedelta (minuten = 3) profile.Save () Return Redirect (profile.create_auth_url ()) berichten.success (verzoek, f'your -profiel is bijgewerkt! ') print ('Profiel bijgewerkt') Return Redirect ('Users: Profile') anders: u_form = userUpDateForm (instance = request.user) p_form = profileUpDateForm (instance = request.user.Profile, initial = {'phone_number': request.user.profile.phone_number if request.user.profile.phone_number else '+1'})) context = { 'u_form': u_form, 'p_form': p_form, 'Titel': 'Update uw profiel', } Return Render (Request, 'Users/Profile.html', context)

Voeg deze import toe

We hebben ook een sjabloon nodig voor deze weergave.
SITE_NAME = 'Django App'
PROTOCOL = 'https'
DOMAIN = 'example.com'

BASE_URL = PROTOCOL + '://' + DOMAIN
nano -gebruikers/sjablonen/gebruikers/profile.html

{ % breidt "base.html" %} uit { % laden Crispy_forms_tags %} {% load feed_filters%} { % blokinhoud %} Bewerk uw profiel { % csrf_token %} Profielinformatie {{u_form | crispy}} {{p_form | crispy}} Update} Gered { % Endblock -inhoud %} { % blok JavaScript %} var form = document.getElementById ('profiel-vorm'); $ ('input'). wijzigen (functie () { var formData = new FormData (form); $ .aJax ({ URL: Window.Location.Href, Type: "Post", Gegevens: FormData, procesdata: onwaar, contentType: False, Time -out: 1000 * 60, Succes: functie (data) { $ (geplaatst) .Removeclass ("Hide"); setTimeout (function () { $ (geplaatst) .addclass ("fade-verborgen"); setTimeout (function () { $ (geplaatst) .AddClass ("Hide"); $ (geplaatst) .Removeclass ("fade-verborgen"); }, 2000); }, 2000); } }); }); { % endblock %}

Je zult merken dat dit een vrij eenvoudige vorm is, maar heeft wat JavaScript erin die automatisch de inhoud van het formulier plaatst terwijl ze worden bijgewerkt. Dit is handig om te hebben, dus u kunt bewerkingen maken zonder elke keer op te dienen.

Vervolgens hebben we URL's nodig die al deze weergaven vertegenwoordigen in de URL -patronen van de gebruikers. Gebruikers/urls.py bewerken en deze code toevoegen:

# ... vorige code, importeren Van django.urls importpad van . Importweergaven app_name = 'gebruikers' urlpatterns = [ #… URL -patronen die we eerder hebben ingevoerd, voeg de volgende drie regels toe pad ('mfa ///', views.mfa, name = 'mfa'), pad ('mfa/onboarding/', views.mfa_onboarding, name = 'mfa_onboarding'), PATH ('Profiel/', views.Profile, name = 'profiel'), ]
nano users/tokens.py
… Vorige code, importeren

... URL -patronen die we eerder hebben ingevoerd, voeg de volgende drie regels toe

Dit is een goed moment om ons project te testen. Maar laten we eerst nog een back -up uitvoeren.
from django.contrib.auth.tokens import PasswordResetTokenGenerator
import six
class TokenGenerator(PasswordResetTokenGenerator):
    def _make_hash_value(self, user, timestamp):
        return (
            six.text_type(user.pk) + six.text_type(timestamp)
        )
account_activation_token = TokenGenerator()
unsubscribe_token = TokenGenerator()
back -up

En voer de server uit. Voordat we naar een Linux -server worden geïmplementeerd, is het een goed idee om twee factorauthenticatie op het account mogelijk te maken. We doen dit naar onze profiel -URL,/Users/Profile/, en controleren het vakje om authenticatie in te schakelen na het invoeren van ons telefoonnummer en vervolgens het formulier in te dienen.

python management.py runserver localhost: 8000

Bezoek de webpagina door naar uw webbrowser te gaan, ik gebruik Google Chrome in dit voorbeeld en voer de URL https in: // localhost: 8000/accounts/profiel/

U kunt indien nodig inloggen en twee factorauthenticatie inschakelen.
nano users/email.py
Dit project heeft een server nodig om uit te voeren, zodat het echt e -mail kan verzenden. Maar eerst hebben we een manier nodig om fouten te zien. U zult merken dat als u de server in de foutopsporingsmodus uitvoert, met instellingen.debug gelijk aan TRUE, de server automatisch fouten toont. Om fouten te tonen zonder de foutopsporingsmodus te gebruiken, die onveilig is op een productieserver, moeten we er een weergave voor toevoegen. De belangrijkste fouten die we moeten kunnen hanteren, zijn:

Fout 500 - Een probleem met onze code Fout 404 - Een pagina die niet werd gevonden (Broken URL) Fout 403 - Een toestemming geweigerd fout

Laten we een nieuwe app toevoegen om deze fouten te verwerken, fouten genoemd.
from django.contrib.auth import get_user_model
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.contrib.sites.shortcuts import get_current_site
from django.core.mail import send_mail
from django.template.loader import render_to_string
from django.utils.encoding import force_bytes
from django.core.mail import EmailMultiAlternatives
from django.shortcuts import render
from .tokens import account_activation_token
from django.template.loader import render_to_string
from django.utils.html import strip_tags
from django.template import Template, Context
from django.conf import settings
import traceback

def send_verification_email(user):
    User = get_user_model()
    mail_subject = '[{}] Activate your account.'.format(settings.SITE_NAME)
    html_message = render_to_string('users/verification_email.html', {
        'user': user,
        'domain': settings.DOMAIN,
        'protocol': 'https',
        'uid': urlsafe_base64_encode(force_bytes(user.pk)),
        'token': account_activation_token.make_token(user),
    })
    send_html_email(user, mail_subject, html_message)
python manag.py startapp fouten

Voeg dit toe aan de instellingen.py zoals we eerder deden, in de instelling Installed_apps, en begin met het toevoegen van verwijzingen naar enkele weergaven in app/urls.py, waarbij app de naam is van uw django -project.

handler404 = 'fouten.views.handler404' handler500 = 'fouten.views.handler500' handler403 = 'fouten.views.handler403'
def send_html_email(user, mail_subject, html_message):
    to_email = user.email
    username = user.username
    if to_email == '':
        return None
    unsub_link = settings.BASE_URL + user.profile.create_unsubscribe_link()
    html_message = html_message + "<p><a href=\"" + unsub_link +  "\" + title=\"Unsubscribe from " + settings.SITE_NAME + " emails\">Unsubscribe</a></p></body></html>"
    msg = EmailMultiAlternatives(mail_subject, strip_tags(html_message), settings.DEFAULT_FROM_EMAIL, [to_email], headers={'List-Unsubscribe' : '<' + unsub_link + '>'},)
    msg.attach_alternative(html_message, "text/html")
    profile = user.profile
    try:
        msg.send(fail_silently=False)
        if not profile.email_valid:
            profile.email_valid=True
            profile.save()
    except:
        profile.email_valid=False
        profile.save()
Dit is alles wat we nodig hebben, behalve foutopvattingen, sjablonen en een klein beetje middleware. Laten we die zoals zo definiëren:

Van django.shortcuts import render, omleiding van django.http import httpResponse van stacktrace.models importfout importeren van fouten.middleware import get_current_exception Van django.contrib.auth.decorators importeren login_required van django.contrib.auth.decorators import user_passes_test Van .logs importeren get_logs Van face.tests import is_superUser_or_Vendor van django.views.decorators.csrf import csrf_exempt uit fouten. Hooglicht importeren hoogtepunt_code Van django.shortcuts importeren omleiding Van django.urls importeer omgekeerde omgekeerde # Maak hier uw weergaven. @login_required @User_Passes_Test (is_superUser_or_Vendor) def -logboeken (verzoek): Logs = Highlight_Code (get_logs ()) Retourneer render (verzoek, 'fouten/live_error.html', {'title': 'Error Logs', 'Pagetitle': 'Fout Logs', 'Notes': 'Dit zijn de recente foutlogboeken.', 'Trace': Logs, 'Full': True}) @login_required @User_Passes_Test (is_superUser_or_Vendor) def logs_api (verzoek): Logs = Highlight_Code (get_logs ()) Retourneer httpresponse (logs) @login_required Def Handler404 (verzoek, uitzondering): Indien niet request.path.endswith ('/'): return Redirect (Request.Path + '/') Retourneer render (verzoek, 'fouten/error.html', {'title': 'Error 404', 'pagetitle': 'Error 404', 'Notes': 'Deze pagina is niet op de server gevonden. Het is mogelijk verplaatst of verwijderd.', 'IS_404': True})) Def Handler500 (verzoek): print (get_current_exception ()) Gebruiker = geen if hasattr (verzoek, 'gebruiker') en request.user en request.user.is_authenticated: gebruiker = request.user poging: Error.objects.create (user = user, stack_trace = get_current_exception (), notes = 'Logged by 500 Handler.') Behalve: passeren Retourneer render (verzoek, 'fouten/error.html', {'title': 'Error 500', 'Pagetitle': 'Error 500', 'Notes': 'Er is een probleem met de server, of met een verzoek van u. Dank je voor je begrip.', 'Trace': Get_current_exception ()}) Def Handler403 (verzoek, uitzondering): Retourneer render (verzoek, 'fouten/error.html', {'title': 'Error 403', 'pagetitle': 'Error 403', 'Notes': 'U hebt geen toestemming om dit verzoek vooraf te vormen. Als u denkt dat dit ten onrechte is, neem dan contact op met de serverbeheerder.', 'IS_403': True}) Def Handler400 (verzoek, uitzondering): Retourneer render (verzoek, 'fouten/error.html', {'title': 'Error 400', 'pagetitle': 'Error 400', 'Notes': 'Dit was een slecht verzoek.'})

Maak hier uw mening.

Laten we vervolgens de middleware definiëren om deze fouten af ​​te handelen. We zullen dit doen door eerst toe te voegen aan middleware_classes in settings.py, met de naam van onze middleware.

Middleware_classes = [ #... vorige middleware 'fouten.middleware.exceptionverbosemiddleware, ]

... Vorige middleware

Laten we vervolgens de middleware toevoegen.
nano users/models.py
van threading import lokaal Traceback importeren Van django.utils.deprecation import Middlewaremixin _error = lokaal () Klasse ExceptionVerBosemiddleware (Middlewaremixin): def process_exception (zelf, verzoek, uitzondering): _error.value = traceback.format_exc () def get_current_exception (): poging: retourneer _error.value behalve attributenError: retourneer geen def set_current_exception (uitzondering): poging: _Error.Value = uitzondering behalve attributenError: print ('Attribute foutinstelling uitzondering.')
# We voegen een functie toe om de huidige uitzondering te krijgen met behulp van een threading -lokaal, waardoor we fouten in onze code kunnen traceren. In termen van sjablonen hebben we er maar één nodig, omdat we de titel in de weergave dynamisch definiëren. De sjabloon hoeft alleen de titel en "Trace" te geven, onze fouttraceback uit de context.
nano -fouten/sjablonen/fouten/error.html

{ % verlengt 'base.html' %} { % blokinhoud %} {{pagetitle}} {{trace}} { % endblock %}

Dit is onze eenvoudigste sjabloon tot nu toe, maar zo gemakkelijk is het om de fouten in ons project te zien. Laten we vervolgens de foutopsporing in instellingen uitschakelen.
# nano app/settings.py
            TimestampSigner().unsign(key, max_age=60 * 60 * 24 * 30) # Zoek deze regel waar deze is ingesteld op waar en verander deze in False
Debug = false

Ga je gang en back -up van de app nu. We zijn klaar om te implementeren naar een externe Linux -server en blijven vanaf daar functies toevoegen.

sudo back -up

Voordat we deze code op een server plaatsen, moeten we bedenken dat er enkele problemen kunnen zijn met de code. Afhankelijk van de zaak, zullen sites die op hen zijn geplaatst, problemen hebben met het plaatsen van spam en moeite met het verwijderen van de spam. Dit zou niet onmiddellijk moeten gebeuren, maar als het gebeurt, zullen we later onderzoeken hoe we de spam automatisch op de site kunnen matigen en het moeilijker kunnen maken voor robots om toegang te krijgen tot de site, samen met het deactiveren van gebruikersaccounts, en de identiteit van een gebruiker verifiëren met een scan van hun ID of een biometrische scan, zoals een vingerafdruk of facial herkenning.

Kijkend naar het voorbeeld van multi -factor authenticatie dat we hebben onderzocht, kunnen in productie dingen anders zijn. Merk op hoe we aanmeldingen beperken en de tokens vervallen. Als robots toegang hebben tot een site, kan twee factorauthenticatie moeilijker zijn, omdat deze codes kunnen invoeren tegelijkertijd de gebruiker. Laten we, om dit te bestrijden, een model in de gebruikersmodellen gebruiken en verklaren hoe we met de site omgaan wanneer we authenticeren met behulp van multi -factor authenticatie met een telefoonnummer. We zullen ook een optie toevoegen om te authenticeren met e -mail. Begin met het bewerken van de gebruikersmodellen met nano.
nano users/views.py
nano -gebruikers/modellen.py

Dit is hoe het model dat we toevoegen, eruit zou moeten zien. We hebben geen methoden nodig, alleen variabelen om een ​​ID op te slaan, de gebruiker, de tijdstempel, vervaldatum, lengte en pogingen tegen elke multi -factor authenticatie (een code zoals 123456 verzonden naar een telefoon of e -mail).

# Een basistoken dat wordt gebruikt om in te loggen op de website Klasse Mfatoken (modellen.model): User = Models.ForeignKey (gebruiker, on_delete = modellen.cascade, gerelateerd_name = 'MFA_TOKENS') timestamp = modellen.datetimeField (standaard = timeZone.now) verloopt = modellen.datetimeField (standaard = timeZone.now) token = modellen.charfield (standaard = '', max_length = 100) lengte = modellen.integerfield (standaard = 6) pogingen = modellen.integerfield (standaard = 0) uid = modellen.charfield (standaard = uuid.uuid4, max_length = 100)
from .email import send_verification_email # Een basistoken dat wordt gebruikt om in te loggen op de website
Laten we ook een voorrecht aan onze gebruiker toevoegen, en we zullen het voorlopig handmatig instellen, voordat we uiteindelijk automatisch migreren naar het in dienst nemen van bevoorrechte gebruikers. Voeg in de gebruikersmodellen deze regel toe aan het profiel:

Verkoper = modellen.booleanfield (standaard = false)

Zoals bij elke wijzigingen in de database, moeten we migraties aanbrengen en de database migreren wanneer we een modellen.py -bestand in Django bewerken. Vergeet niet dat we hiervoor eerst de bron gebruiken (als het nog niet is gebruikt sinds de terminal open was) en vervolgens python manag.py om de migraties te maken en te migreren.

CD-projectdirectory-you-genoemde # (indien nodig) Bron venv/bin/activeren python manag.py makemigrations && python manag.py migrate

(indien nodig)
        # Voor nu kunt u alle accounts inschakelen die u als leveranciers hebt gemaakt met behulp van de shell.
    # python management.py shell
van gebruikers.models importprofiel importeren
p = profile.Objects.get (user__UserName = 'Charlotte'))
P. Vendor = waar
P.Save ()
Uitgang()
# Laten we nu onze multi -factor authenticatieweergave evolueren om dit token te gebruiken. Eerst moeten we onze MFA -helperhulpprogramma's wijzigen. Nano gebruiken,
nano -gebruikers/mfa.py

van django.utils import timezone willekeurig importeren DateTime importeren Van django.conf Importinstellingen van feed.middleware import get_current_request Van django.contrib Import berichten uit .email import send_html_email Traceback importeren van .Models import mfatoken account_sid = settings.twilio_account_sid auth_token = settings.twilio_auth_token source_phone = instellingen.phone_nummer def send_text (target_phone, tekst): van Twilio.rest import client poging: client = client (account_sid, auth_token) Als len (target_phone)> = 11: message = client.Messages.Create ( tot = target_phone, from_ = source_phone, body = tekst + 'tekst stop om te annuleren.') behalve: berichten.warning (get_current_request (), 'Er was een fout die het bericht verzenden.') print (traceback.format_exc ()) def get_num_length (num, lengte): n = '' voor X in bereik (lengte): n = n + str (num) Return int (n) def send_verification_text (gebruiker, token): lengte = user.profile.verification_code_length code = random.randint (get_num_length (1, lengte), get_num_length (9, lengte)); token.token = code token.expires = timezone.now () + datetime.timedelta (minuten = instellingen.auth_valid_minutes) token.save () send_user_text (gebruiker, "Uw verificatiecode voor {} is {}". Format (settings.site_name, str (code)))) def send_verification_email (gebruiker, token): lengte = user.profile.verification_code_length code = random.randint (get_num_length (1, lengte), get_num_length (9, lengte)); token.token = code token.expires = timezone.now () + datetime.timedelta (minuten = instellingen.auth_valid_minutes) token.save () send_html_email (gebruiker, "Uw verificatiecode voor {} is {}". Format (settings.site_name, str (code)), "Beste {}, uw verificatiecode voor {} is {} str (code), str (code), settings.site_name))) def send_user_text (gebruiker, tekst): send_text (user.profile.phone_nummer, tekst) def check_verification_code (gebruiker, token, code): token.attonpts = token.Attempts + 1 profiel = user.profile result = (token! = Geen en code! = '' en token.token == code en (token.expires> timeZone.now ()) en token.attempts <= settings.mfa_token_attempts) If token.Antempts <3 en resultaat: Profiel.verification_code_length = 6 elif -token. ATTONTEN> 1 en niet resulteren: Profiel.verification_code_length = profile.verification_code_length + 2 if profil.verification_code_length> settings.mfa_token_length: profile.verification_code_length = settings.mfa_token_length token.save () profile.Save () Retourresultaat

# De gebruiker verifiëren met behulp van zijn e -mail- of telefoonnummer def mfa (verzoek, gebruikersnaam, usertoken): token = mfatoken.objects.filter (uid = gebruikersnaam, vervalt__gt = timeZone.now () + datetime.timedelta (seconden = 30)). Order_by ('-TimeStamp'). Laatste () # Filter de token door de waarde die in de url (een uuid) zo niet token: token = mfatoken.objects.create (user = user.objects.filter (profile__uuid = gebruikersnaam) .first (), uid = gebruikersnaam, vervolgt = timeZone.now () + datetime.timedelta (seconden = 115)) user = user.objects.filter (id = token.user.id) .first () # haal de gebruiker van het token Indien niet gebruiker en request.user.is_authenticated: return Redirect (reverse ('feed: home')) # Als ze al zijn geverifieerd, log ze dan in zo niet gebruiker: haal toestemming op () # weigeren als er geen gebruiker is gevonden next = request.get.get ('next', '') zo niet gebruiker.profile.enable_two_factor_authentication en user.is_active en user.profile.check_auth_token (usertoken, token): # Controleer het AUTH -token auth_login (verzoek, gebruiker, backend = 'django.contrib.auth.backends.modelbackend') # Log in de gebruiker in als ze nog niet zijn ingelogd user.profile.mfa_expires = timezone.now () + datetime.timedelta (minuten = settings.login_valid_minutes) # Stel een verval van op hun multi -factor authenticatie User.Profile.Save () Retourneer httpResponseredirect (volgende als volgende! = '' else reverse ('Landing: Landing')) # Verwijder de gebruiker naar de volgende pagina zo niet gebruiker.profile.mfa_enabled: # Controleer of MFA is ingeschakeld zo niet check_verification_time (gebruiker, token): # Controleer de tijd user.profile.mfa_enabled = false # wissen het telefoonnummer user.profile.enable_two_factor_authentication = true # inschakelen mfa user.profile.phone_nummer = '+1' # Schakel het telefoonnummer uit user.profile.save () # Opslaan het profiel auth_login (verzoek, gebruiker, backend = 'django.contrib.auth.backends.modelbackend') # Log de gebruiker in als hun MFA niet is ingeschakeld berichten.warning (verzoek: 'Voer een geldig telefoonnummer in en verifieer het met een code.') Return Redirect (reverse ('gebruikers: mfa_onboarding'))) if request.method == 'post' en niet fraud_detect (verzoek, true): # Als het verzoek een postverzoek is Form = tfaform (request.Post) # Bestrijd het formulier code = str (form.data.get ('code', none)) # Koop de code Als code en code! = '' en code! = Geen: # Zorg ervoor dat het niet leeg is token_validated = user.profile.check_auth_token (usertoken) # Controleer het AUTH -token p = user.profile is_verified = check_verification_code (gebruiker, token, code) # Controleer de code p.mfa_authenticated = is_verified if token_validated: # als alles If is_verified: # is in volgorde user.profile.mfa_enabled = true # inschakelen mfa (indien niet al ingeschakeld) User.Profile.Save () auth_login (verzoek, gebruiker, backend = 'django.contrib.auth.backends.modelbackend') # Log in de gebruiker in face = user.faces.filter (session_key = geen) .Last () P.MFA_EXPIRES = TIMEZONE.NOW () + DateTime.Timedelta (minuten = instellingen.login_valid_minutes) P.Save () berichten.success (verzoek: 'U bent geverifieerd. Welkom.') QS = '?' Voor de sleutel, waarde in request.get.items (): # Bouw een querystring voor de volgende parameter (indien aanwezig) qs = qs + key + '=' + waarde + '&' Als volgende! = '' en niet (next.startswith ('/Accounts/Logout/') of Next.StartSwith ('/Accounts/Login/') of Next.StartSwith ('/admin/login/') of Next.StartsWith ('/Accounts/Register/')): Retourneer HTTPRESPONSERedirect (volgende) # redirect elif next.startswith ('/accounts/logout/') of next.startswith ('/accounts/login/') of next.startswith ('/Accounts/register/'): return Redirect (reverse ('/')) elif request.meta.get ('http_referer', '/').startswith('/accounts/login/'): return Redirect (reverse ('/')) Elif niet de volgende: return Redirect (reverse ('/')) anders: Return HttPreSeredirect (reverse ('verifieer: leeftijd') + '? volgende =' + request.meta.get ('http_referer', '/')) anders: berichten.warning (verzoek: 'De code die u hebt ingevoerd, is niet herkend. Probeer het opnieuw.') elif Not token_validated: # Als het token ongeldig was berichten. Waren (verzoek, 'het URL -token is verlopen of is niet herkend. Probeer het opnieuw.' uitloggen (verzoek) Return Redirect (Reverse ('Users: Login')) Als p.mfa_attempts> 3: # als er te veel pogingen waren berichten.warning (verzoek, 'uhebben de onjuiste code meer dan 3 keer ingevoerd. Stuur jezelf een nieuwe code. ') P.Verification_Code = geen P.Save () elif user.profile.can_send_mfa <timeZone.now (): user.profile.mfa_attempts = 0 user.profile.can_send_mfa = timezone.now () + datetime.timedelta (minuten = 2) User.Profile.Save () if form.data.get ('send_email', false): # Verzend de e -mail (of tekst) send_mfa_verification_email (gebruiker, token) anders: send_verification_text (gebruiker, token) berichten.success (verzoek: "Voer de code in die wordt verzonden naar uw telefoonnummer of e -mail. De code verloopt binnen 3 minuten.") elif user.profile.can_send_mfa <timeZone.now () + datetime.timedelta (seconden = 115): berichten Form = tfaform () hide_logo = geen if user.profile.hide_logo: hide_logo = true if request.user.is_authenticated: return redirect (reverse ('/')) # Render het formulier (voor Get Requests) Return Render (Request, 'Users/Mfa.html', {'title': 'Enter Code', 'Form': Form, 'XSMall': True, 'User': User, 'Hide_Logo': Hide_Logo, 'Accl_Logout': User.Profile.Shake_to_to_to_to_to_to_to_to_to_to_to_to_to_to_to_to_to_to_to_to_to_to_to_to_to_to_to_to_to_to_lo
nano users/views.py
Verifieer de gebruiker met behulp van zijn e -mail- of telefoonnummer
# Filter het token door de waarde die is doorgegeven in de URL (een UUID)
# Als deze sessie niet is gemaakt, maak deze dan aan
Haal de gebruiker uit het token

Als ze al zijn geverifieerd, log ze dan in

Ontken als er geen gebruiker is gevonden
# Controleer het AUTH -token
            send_verification_email(user) # Log in de gebruiker in als ze nog niet zijn ingelogd
Stel een verval van op hun multi -factor authenticatie

Direct de gebruiker om naar de volgende pagina

Controleer of MFA is ingeschakeld
# Controleer de tijd
Wis het telefoonnummer

Schakel MFA in

Schakel het telefoonnummer uit
nano users/templates/users/resend_activation.html
Sla het profiel op

Log de gebruiker in als zijn MFA niet is ingeschakeld

Als het verzoek een postverzoek is
Instantiëren de vorm

Krijg de code

Zorg ervoor dat het niet leeg is
def sendwelcomeemail(user):
    User = get_user_model()
    html = open('{}/users/welcome_email.html'.format(settings.BASE_DIR)).read()
    subject = 'Welcome to ' + settings.SITE_NAME + ', {{ username }}!'
    template = Template(html)
    subjtemplate = Template(subject)
    context = Context({'username': user.username, 'base_url': settings.BASE_URL, 'model_name': 'Daisy Holton, 'site_name': settings.SITE_NAME})
    renderedtemplate = template.render(context)
    subjcontext = Context({'username': user.username})
    subjrenderedtemplate = subjtemplate.render(subjcontext)
    send_html_email(user, subjrenderedtemplate, renderedtemplate)
Controleer het AUTH -token

Controleer de code

Als alles
Is in orde

Schakel MFA in (indien nog niet ingeschakeld)

Log in de gebruiker in

Bouw een querystring voor de volgende parameter (indien aanwezig)

Omleiden

Als het token ongeldig was

Als er te veel pogingen waren
# Stuur de e -mail (of sms)
Render het formulier (voor get -aanvragen)

Wanneer we deze code toevoegen, moet u de functie importeren om een ​​e -mail te verzenden. Bovenaan het bestand viewt de gebruikers (met andere imports) toevoegen

uit .mfa import send_verification_email als send_mfa_verification_email
Nu moeten we die functie schrijven voordat dit zal werken. Het zou onze e -mailfunctie moeten uitbreiden en eenvoudig een e -mail naar de gebruiker verzenden met de verificatiecode.

nano -gebruikers/mfa.py

def send_verification_email (gebruiker, token): lengte = user.profile.verification_code_length code = random.randint (get_num_length (1, lengte), get_num_length (9, lengte)); token.token = code token.expires = timezone.now () + datetime.timedelta (minuten = instellingen.auth_valid_minutes) token.save () send_html_email (gebruiker, "Uw verificatiecode voor {} is {}". Format (settings.site_name, str (code)), "Beste {}, uw verificatiecode voor {} is {} str (code), str (code), settings.site_name)))
Dus dit werkt allemaal geweldig, nu hebben we een multi -factor authenticatiesysteem dat afhankelijk is van een telefoonnummer of e -mail om in te loggen. Maar we hebben ook een manier nodig om gebruikers te verwijderen, of op zijn minst verbergen die niet met onze voorwaarden samenwerken. Dit kunnen spammers, robots of iemand zijn die niet goed betekent voor ons werk. Bekijk een weergave die ik heb om gebruikers op mijn website te bewaken:

# importeren Van django.contrib.auth.decorators importeren login_required van django.contrib.auth.decorators import user_passes_test Van .Tests import is_superUser_or_Vendor # we moeten deze test maken @login_required @User_Passes_Test (is_superUser_or_Vendor) Def gebruikers (verzoek): # Haal een lijst met gebruikers op new_today = user.objects.filter (is_active = true, date_joined__gte = timeZone.now () - DateTime.Timedelta (uren = 24)). Count () new_this_month = user.objects.filter (is_active = true, date_joined__gte = timeZone.now () - DateTime.Timedelta (uren = 24*30)). Count () abonnees = user.objects.filter (is_active = true, profile__subscribed = true) .count () Return Render (Request, 'Users/Users.html', { # Returners in een sjabloon 'Titel': 'All Accounts', 'gebruikers': user.objects.all (), 'new_today': new_today, 'new_this_month': new_this_month, 'Abonnees': abonnees })

invoer
We moeten deze test maken

Koop een lijst met gebruikers

Retour u gebruikers in een sjabloon
Merk op dat deze code een test gebruikt, we moeten deze test in een tests.py -bestand verklaren en importeren. Gebruikers/tests.py bewerken, laten we de test maken.

def is_superUser_or_Vendor (gebruiker): retourneer gebruiker.profile.Vendor of user.is_superUser

Dit is in combinatie met de users/users.html -sjabloon, die er zoiets uitziet:
{ % verlengt 'base.html' %} { % load app_filters %} { % blokinhoud %} Alle geregistreerde bezoekers {{new_today | nts | capitalize}} Nieuw vandaag, {{new_this_month | nts}} nieuw deze maand, {{abonnees | nts}} abonnees, {{users.count | nts}} totaal. { % voor gebruikers in gebruikers %} { % omvat 'gebruikers/_user.html' %} { % endfor %} { % endblock %}

user.html. Bij het gebruik van een sjabloon met een subtemplate en niet gebruikt, is het een goed idee om een ​​onderstrepingsteken toe te voegen (

Merk op dat dit veel Jinja is, je hebt misschien niet al deze variabelen gedefinieerd. Maar dit is hoe mijn code eruit ziet.
    # { % load app_filters %}


    
      @{{user.UserName}} - {{user.Profile.Name}} ({{user.Profile.Prefeerred_Name}}))
      Laatst gezien {{user.profile.last_seen | datum: "f d, y"}} {{user.profile.last_seen | tijd: "h: i"}}
      Verbonden op {{user.Profile.Date_joined | datum: "f d, y"}} {{user.Profile.Date_Joined | time: "h: i"}}
      {{user.email}}
      { % if user.profile.phone_number %} {{user.profile.phone_number}} { % endif %}
      { % if user.verifications.Last %}
      '{{user.verifications.last.full_name}}'
       {{user.verifications.Last.Document_Number}}
       {{user.verifications.Last.BirthDate}}
       ID -front
       ID terug
      { % endif %}
      #{{user.id}}
      { % if user.profile.subscribed %} geabonneerd { % else %} niet geabonneerd { % endif %}
    
    { %Als het niet gebruiker.is_superUser %}
    { % omvat 'gebruikers/toggle_active.html' %}
    { % endif %}
    { % Autoescape Off %}    
    {{user.bio}}
    { % endautoScape %}
    
    { % if user.Profile.Identity_verified %} geverifieerde gebruiker. { % else %} niet -geverifieerde gebruiker. { % endif %} verificaties: {{user.verifications.count | nts}}
{{user.id}} </mall>

We hebben ook een andere subtemplate nodig, toggle_active.html. Deze sjabloon moet een formulier zijn waarmee we kunnen schakelen of een gebruiker actief is.

{ % if user.is_active %} { % else %} { % endif %}

We moeten ook een weergave toevoegen om gebruikersactiviteit en geschikte URL -patronen te schakelen. Terwijl we bezig zijn, laten we een weergave toevoegen om een ​​gebruiker te verwijderen voor het geval we dat nodig hebben.

van django.views.decorators.csrf import csrf_exempt @CSRF_ Exempt @login_required @User_Passes_Test (is_superUser_or_Vendor) def toggle_user_active (verzoek, pk): user = user.objects.get (id = pk) if request.method == 'post': user.is_active = niet user.is_active User.Save () return httPresponse ('' if user.is_active anders '')) # Importeren Van django.contrib.auth.mixins import LoginRequiredMixin, UserPassestestMixin Van django.views.generic importeren deleteView Class UserDeletEView (LoginRequiredMixin, UserPassestestMixin, DeleteView): model = gebruiker Succes_url = '/' # The Redirect on Success URL def get_context_data (self, ** kwargs): context = super (). get_context_data (** Kwargs) Retourcontext def test_func (self): # test of de gebruiker superuser is en toestemming heeft om te verwijderen user = self.get_object () if self.request.user! = Gebruiker en self.request.user.is_superUser: Return true Keer onwaar terug

Invoer

De omleiding op succes -URL
# Test of de gebruiker superuser is en toestemming heeft om te verwijderen
    # Hoewel dit praktisch is wanneer dat nodig is, zou het verwijderen van een gebruiker meestal niet nodig moeten zijn, kunnen we gewoon de zichtbaarheid van gebruikers die de site bezoeken schakelen als we ze moeten afwijzen.
    # De URL -patronen die we hebben toegevoegd, zien er zo uit. Met nano, bewerk gebruikers/urls.py en voeg deze regels toe:
            TimestampSigner().unsign(key, max_age=60 * settings.AUTH_VALID_MINUTES) # nano -gebruikers/urls.py
De regels moeten in de lijst met paden in de gebruikersweergaven gaan, vóór het einde "]" maar na het begin "[".

#… path ('user // delete/', userDeletEview.as_view (template_name = 'blog/user_confirm_delete.html'), name = 'delete-user'), pad ('user // active/', views.toggle_user_active, name = 'toggle-user-active'), #…

source venv/bin/activate
python manage.py makemigrations && python manage.py migrate

Zorg er nu voor dat u de site een back -up maakt, zodat u deze op de webserver kunt downloaden waaraan we blijven werken. Van de opdrachtregel,

sudo back -up

Nu wordt onze site een back -up gemaakt.

Dus nu hebben we nog een paar nuttige functies. Maar hoe zit het met het grote geheel hier? Deze code is nog steeds niet toegankelijk via internet, we hebben nog geen e -mailserver en we moeten onze app uitbreiden om een ​​uitgebreid verificatieproces op te nemen, evenals soepele lay -outs om ons te helpen de site te verkennen, samen met beveiligde protocollen voor authenticerende bevoorrechte gebruikers.
# We zullen dit allemaal bereiken. Het belangrijkste voor nu zal deze code gewoon online krijgen, wat we kunnen doen met slechts een paar regels bash op een Ubuntu -server. U moet hiervoor een server huren, tenzij u thuis een server hebt en een zakelijk internetabonnement waarmee u poorten kunt openen. Ik heb persoonlijk mijn website uitgevoerd op een HP Z440 die in mijn appartement is geïnstalleerd, maar het is meestal veel goedkoper voor basisbehoeften om een ​​virtuele privéserver (VPS) te huren.
        if user and user.profile.can_login < timezone.now(): # Houd er rekening mee dat de code die we nu uitvoeren relatief dun is, deze moet worden onderhouden en verbeterd voordat we klaar zijn om te gebruiken wat we hebben om een ​​product te bouwen. Zorg ervoor dat u voorzichtig bent wat u doet met internet, zorg ervoor dat als u deze site publiekelijk op het web op een Linux -server implementeert, u een plan hebt om ongewenste interacties met uw website te blokkeren. Dit zal in het begin waarschijnlijk geen probleem zijn, maar we zullen verschillende oplossingen onderzoeken om dit te bestrijden, waaronder machine learning, kunstmatige intelligentie en computer vision. Wanneer het een probleem wordt, kijk dan verder in deze tekst voor een oplossing.
            # Wat een VPS huurt, zijn er veel plaatsen waar u naartoe kunt. Google Cloud heeft VPS -servers, Ionos, Kamatera, Amazon AWS en meer providers bieden cloudserveroplossingen die aan onze behoeften voldoen.
                return redirect(user.profile.create_auth_url()) # U moet door hun formulieren klikken en een plan selecteren om aan de slag te gaan. U kunt met een provider gaan met een basisplan, maar zorg ervoor dat u de poortpoorten kunt openen om een ​​e -mail te openen om e -mail te verzenden (dit moet poort 587 en poort 25 zijn), sommige providers blokkeren deze poorten. Tot nu toe heb ik de beste ervaring gehad met Ionos en Kamatera, beiden zullen me toestaan ​​om onbeperkte e -mail te sturen en hun prijzen zijn vrij goedkoop.
            else: # U zult verbinding maken met uw nieuwe server via een protocol genaamd SSH of Secure Shell, waarmee u op afstand met de server kunt interface met de server, precies zoals uw personal computer, vanaf uw personal computer. Wanneer u de server instelt, zal de hostingprovider u waarschijnlijk vragen om een ​​SSH -toets toe te voegen, of zij zullen u een gebruikersnaam en wachtwoord geven. De SSH -toets is hoe u inlogt op de server vanaf de opdrachtregel om de code te bewerken. Gebruik de onderstaande SSH-Keygen-opties om een ​​SSH-toets te genereren.
        else: # SSH-keygen
            user = User.objects.filter(username=username).first() # Sla het bestand op en overschrijf het als dat nodig is, het is goed om uw SSH -toetsen te roteren als u dat nog niet hebt gedaan. Nu kunt u de volgende opdracht gebruiken om uw SSH -toets te zien. U wilt het naar uw externe server kopiëren, zodat u het kunt gebruiken om te verifiëren.
                profile.can_login = timezone.now() + datetime.timedelta(seconds=15) # Cat ~/.ssh/id_rsa.pub
Als u geen SSH-sleutel kon zien bij het typen van die opdracht (een lange reeks cijfers en letters die beginnen met "SSH-RSA AAA"), probeer dan een RSA-sleutel te genereren (ze zijn veiliger, dus ik adviseer ze om ze te gebruiken.) De volgende code zal een 4096 bit RSA SSH SSH-sleutel genereren.

ssh -keygen -t rsa -b 4096

Maak een VPS met Ubuntu, maar u bent van plan dit te doen. Nadat u een VPS hebt gemaakt door door de formulieren op de website van de providers te klikken (Kamatera.com, Ionos.com of iets dergelijks), wilt u inloggen. Gebruik hiervoor de SSH -opdracht met uw IP -adres (het adres dat eruit ziet als xx.xx.xx.xx). U moet ook gevoelig zijn voor de standaardgebruikersnaam op de server die we hebben gemaakt, bijvoorbeeld Ubuntu.

ssh ubuntu@xx.xx.xx.xx

U kunt om een ​​wachtwoord worden gevraagd, als u om een ​​wachtwoord wordt gevraagd, voert u dit in. We zullen de standaardgebruikersnaam niet gebruiken, dus laten we beginnen met het maken van een nieuwe gebruiker en het toevoegen van een SSH -toets aan hun account.
nano users/sms.py
Laten we beginnen met het toevoegen van een nieuw SSHD_CONFIG -bestand, dat de server vertelt hoe SSH te gebruiken.
# nano sshd_config
# # Dit is het SSHD Server-systeembrede configuratiebestand.  Zien
# sshd_config (5) voor meer informatie.

# Deze SSHD is samengesteld met pad =/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

# De strategie die wordt gebruikt voor opties in de standaard sshd_config verzonden met
# OpenSSH is om opties op te geven met hun standaardwaarde waar
# mogelijk, maar laat ze becommentarieerd.  Ongecomplimeerde opties overschrijven de
# standaardwaarde.

#Port 22
#Addressfamilie
#ListenAddress 0.0.0.0
#ListenAddress ::

#HostKey/etc/ssh/ssh_host_rsa_key
#HostKey/etc/ssh/ssh_host_ecdsa_key
#HostKey/etc/ssh/ssh_host_ed25519_key

# Cijfers en keying
#REKEYLIMIT standaard geen

# Logging
#SYSLOGFACILITY AUTH
#LogleVel info

# Authenticatie:

#Logingracetime 2m
#PermitroootLogin verboden Password
#StrictModes Ja
#MaxAuthtries 6
#MaxSessions 10

PubKeyAuthentication Ja

# Verwacht .SSH/Authorized_Keys2 zal in de toekomst standaard worden genegeerd.
AuthorizedKeysFile .ssh/Authorized_Keys .ssh/Authorized_Keys2

#Authorizedprincipalsfile geen

#AuthorizedKeysCommand geen
#AuthorizedKeysCommanduser Niemand

# Om dit te laten werken, hebt u ook hostsleutels nodig in/etc/ssh/ssh_ bekende_hosts
#Host -gebaseerdAuthentication Nee
# Wijzig naar ja als u niet vertrouwt ~/.ssh/bekende_hosts voor
# Host -basedauthenticatie
#IgnoreUser Bekend Hosts Nee
# Lees de bestanden van de gebruiker ~/.rhosts en ~/.shosts niet
#Ignorerhosts ja

# Wijzig hier niet in om getunnelde tunneltonnel wachtwoorden voor de gewone tekstwachtwoorden uit te schakelen!
WachtwoordAuthentication Nee
#PermItemPtypasswords Nee

# Wijzig naar ja om uitdagingswachtwoorden van de uitdaging in te schakelen (pas op voor problemen met
# Sommige PAM -modules en threads)
KBDInteractiveAuthentication no

# Kerberos -opties
#Kerberosauthentication nee
#Kerberosorlocalpasswd ja
#Kerberosticketcleanup ja
#Kerberosgetafstoken nee

# GSSAPI -opties
#Gssapiauthentication no
#GssapicleanUpcredentials Ja
#GssapistrictAcceptorcheck Ja
#Gssapikeyexchange nr

# Stel dit in op 'ja' om PAM -authenticatie, accountverwerking mogelijk te maken,
# en sessieverwerking. Als dit is ingeschakeld, zal PAM -authenticatie
# worden toegestaan ​​door de KBDinteractiveAuthentication en
# WachtwoordAuthentication.  Afhankelijk van uw PAM -configuratie,
# PAM -authenticatie via KBDinteractiveAuthentication kan omzeilen
# De instelling van "PermitRootLogin zonder-Password".
# Als u gewoon wilt dat het PAM -account en de sessiecontroles zonder uitvoeren
# PAM -authenticatie, schakel dit vervolgens in, maar stel wachtwoordAuthentication in
# en KBDInteractiveAuthentication to 'No'.
USEPAM ja

#AllowAgentforwarding Ja
#Allowtcpforwarding Ja
#Gatewayports nee
X11forwarding ja
#X11DisplayOffset 10
#X11uselocalhost Ja
#Permittty ja
Printmotd nee
#PrintLastlog Ja
#Tcpkeepalive ja
#PermitUsErEnvironment no
#Compressie vertraagd
#ClientaliveInterval 0
#ClientaliveCountMax 3
#Usedns nee
#Pidfile /run/sshd.pid
#MaxStartups 10: 30: 100
#Permittunnel nee
#ChRootDirectory None
#VersionAddendum geen

# geen standaard bannerpad
Banner /etc /banner

# Sta de klant in staat om de locale omgevingsvariabelen te passeren
AcceptEnv Lang LC_*

# Verhaal de standaard van geen subsystemen
Subsysteem SFTP/usr/lib/openssh/sftp-server

# Voorbeeld van overhegende instellingen per gebruiker
#Match -gebruiker anoncvs
# X11forwarding nee
# TOEMAAKTCPFORWARDEN
# Permittty nee
# Forcecommand CVS Server
PermitRootLogin nee
# Dit is het SSHD Server-systeembrede configuratiebestand.  Zien
# sshd_config (5) voor meer informatie.
# Deze SSHD is samengesteld met pad =/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
# De strategie die wordt gebruikt voor opties in de standaard SSHD_config verzonden met
# OpenSSH is om opties op te geven met hun standaardwaarde waar
mogelijk, maar laat ze becommentarieerd. Ongecomplimeerde opties overschrijven de

Standaardwaarde.

Poort 22
# Adresfamilie elke
AUTH_VALID_MINUTES = 3 # LuisterAddress 0.0.0.0
Luisteraddress ::

Hostkey/etc/ssh/ssh_host_rsa_key

Hostkey/etc/ssh/ssh_host_ecdsa_key
# Hostkey/etc/ssh/ssh_host_ed25519_key
# Cijfers en sleutel
# Rekeylimit standaard geen
Houtkap

Syslogfaciliteit auth

Loglevelinfo
# Authenticatie:
Logingracetime 2m

PermitRootLogin verboden Password

StrictModes ja
nano users/templates/users/mfa.html
MaxAuthtries 6

MaxSessions 10

Verwacht .SSH/Authorized_Keys2 zal in de toekomst standaard worden genegeerd.
Geautoriseerd principals

Geautoriseerde KeysCommand geen

AuthorizedKeysCommanduser Niemand
nano users/templates/users/mfa_onboarding.html
Om dit te laten werken, hebt u ook hostsleutels nodig in/etc/ssh/ssh_ bekende_hosts

Host -basedauthentication nr

Wijzig naar ja als u niet vertrouwt ~/.ssh/bekende_hosts voor
Host -basedauthenticatie

Negeerderbekend Hosts nee

Lees de ~/.rhosts van de gebruiker en ~/.shosts niet

Onwetendhosts ja

Wijzig hier om NEE!

PermitemPtypassWords Nee

Wijzig naar ja om uitdagingen voor uitdagingsrespons in te schakelen (pas op voor problemen met
# Sommige PAM -modules en draden)
Kerberos -opties

Kerberosauthentication nr

KerberosorlocalPasswd ja
# KerberosticketCleanup Ja
Kerberosgetafstoken nee

GSSAPI -opties

Gssapiauthentication nr
nano users/templates/users/profile.html
GssapicleanUpcredentials Ja
Gssapistrictacceptorcheck ja

Gssapikeyexchange nr

Stel dit in op 'ja' om PAM -authenticatie, accountverwerking mogelijk te maken,

en sessieverwerking. Als dit is ingeschakeld, zal PAM -authenticatie

worden toegestaan ​​door de KBDinteractiveAuthentication en
# WachtwoordAuthentication.  Afhankelijk van uw PAM -configuratie,
# PAM -authenticatie via KBDinteractiveAuthentication kan omzeilen
de instelling van "permitRootLogin zonder-Password".

Als u gewoon wilt dat het PAM -account en de sessiecontroles zonder uitvoeren

PAM -authenticatie, schakel dit vervolgens in, maar stel wachtwoordAuthentication in
backup
en KBDInteractiveAuthentication voor 'nee'.

ToyAgentforwarding Ja

Toegestaan ​​met ja
python manage.py runserver localhost:8000
Gatewayports nee

X11displayoffset 10

X11uselocalhost Ja

Permitty ja

PrintLastlog ja

Tcpkeepalive ja

VergunningUsReMIrivery no

Compressie vertraagd

ClientaliveInterval 0

ClientaliveCountMax 3

Gebruikte nr.
python manage.py startapp errors
Pidfile /run/sshd.pid

MaxStartups 10: 30: 100

Permittunnel nee
handler404 = 'errors.views.handler404'
handler500 = 'errors.views.handler500'
handler403 = 'errors.views.handler403'
Chrootdirectory geen

VersieAddendum geen

Geen standaardbannerpad
# Sta de klant in staat om de locale omgevingsvariabelen te passeren
Verhaal de standaard van geen subsystemen

Voorbeeld van overhegende instellingen per gebruiker

Match user anoncvs
    # X11forward no
Toegestane nr.

Permitty nee

Forcecommand CVS -server
from threading import local
import traceback
from django.utils.deprecation import MiddlewareMixin

_error = local()

class ExceptionVerboseMiddleware(MiddlewareMixin):
    def process_exception(self, request, exception):
        _error.value = traceback.format_exc()

def get_current_exception():
    try:
        return _error.value
    except AttributeError:
        return None

def set_current_exception(exception):
    try:
        _error.value = exception
    except AttributeError:
        print('Attribute error setting exception.')
Vergeet niet dat Ctrl+X en Y om het bestand op te slaan. Laten we vervolgens een basisscript schrijven met de naam Initialize (allemaal in de standaard Home Directory van onze gebruiker).

nano initialiseren

Met je SSH -sleutel die je hebt gevonden met CAT. (.ssh/id_rsa.pub)
nano errors/templates/errors/error.html
#!/bin/bash sudo apt install -y nano git openssh -server sudo cp sshd_config/etc/ssh/sshd_config sudo -service ssh opnieuw opstarten sudo -service sshd herstart Echo "/Root/.SSH/ID_RSA" | sudo su root -c "ssh -keygen -t rsa -n ''" echo "root ssh key:" sudo su root -c "cat /wortel/.ssh/id_rsa.pub" sudo addUser--Disabled-Password ---gecos "" team sudo passwd -d team sudo usermod -ag sudo -team echo "/home/team/.ssh/id_rsa" | SU Team -c "SSH -Keygen -T RSA -n ''" cat /home/team/.ssh/id_rsa.pub >> /home/team/.ssh/authorized_keys echo '' >> /home/team/.ssh/authorized_keys Echo "Team SSH Key:" cat /home/team/.ssh/id_rsa.pub
!/Bin/bash

Laten we, om u door dit bestand te leiden, regel voor regel beginnen. De eerste regel vertelt de compiler dat dit een bash -script is. Vervolgens installeren we afhankelijkheden, kopiëren sshd_config naar de juiste directory, starten SSH opnieuw op, genereren SSH -toetsen voor root, het toevoegen van het team van de gebruiker '(u kunt een naam kiezen die u hiervoor leuk vindt, gebruik de opdracht AddUser met hun naam en gehandicapt wachtwoord voor nu). We voegen ook een team toe aan de Sudo -groep, genereren hun SSH -sleutel, voegen ook onze sleutel toe aan geautoriseerde toetsen en die van hen en drukken hun sleutel af. Deze nieuwe gebruiker zal zijn hoe we inloggen op de site.

Ga in een nieuwe terminal door en open de server opnieuw.
nano app/settings.py
ssh team@xx.xx.xx.xx

Je zou deze keer geen wachtwoord nodig hebben, omdat je een SSH -toets hebt. We hebben ook inloggen met een wachtwoord uitgeschakeld om de site veiliger te houden.

Nu begint deze server volledig leeg zonder informatie. Laten we beginnen met het klonen van ons project van Git, zodat we het kunnen downloaden en uitvoeren op de externe machine. Druk eerst uw SSH -sleutel op de externe server die via SSH is verbonden, op:
DEBUG = False
Cat ~/.ssh/id_rsa.pub

Plak deze sleutel vervolgens in de GIT -instellingen zoals we eerder deden om onze Git -repository in te stellen. We kunnen ons project nu rechtstreeks op de server klonen. Zorg ervoor dat je het project eerst lokaal hebt geback -ups, dus het staat op de GIT -server om te downloaden.

git kloon git: //github.com/you/yourproject.git
sudo backup
Perfect. Nu zijn alle bestanden hier. We kunnen ze zien met LS

LS

Laten we nu beginnen met het instellen van de server. Kopieer eerst uw projectmap naar een eenvoudige, memorabele naam die we voor het project zullen gebruiken.

cp -r uw project whatyoucalledit

Waar "Whatyoucalledit" de nieuwe naam van uw project is. Vervolgens moeten we een basishulpprogramma bouwen om de server in te stellen. We zullen dit hulpprogramma opslaan en in de toekomst gebruiken. Om dit hulpprogramma te bouwen, laten we een gebruiker binair maken om te bepalen hoe we een script bewerken. Bash gebruiken, bewerken/usr/bin/ascript
nano users/models.py
sudo nano/usr/bin/ascript

Zorg ervoor dat je Sudo daar gebruikt, dus je hebt machtigingen om het bestand te bewerken. Voeg in het bestand deze regels toe:

#!/bin/bash als [ ! -f/usr/bin/$ 1]; Dan sudo touch/usr/bin/$ 1 echo "#!/bin/bash" >>/usr/bin/$ 1 sudo chmod a+x/usr/bin/$ 1 sudo nano/usr/bin/$ 1 echo $ 1 | sudo tee -a /etc /ascripts anders sudo chmod a+x/usr/bin/$ 1 sudo nano/usr/bin/$ 1 fi
# !/Bin/bash
!/bin/bash ">>/usr/bin/$ 1

Onthoud dat dit script een argument, de scriptnaam, als $ 1 neemt. Eerst controleert het of het bestand bestaat of anderszins maakt, voegt de eerste regel toe om te verklaren dat het script bash is, zijn machtigingen verandert, bewerkt het en voegt zijn naam toe aan /etc /ascripts waarmee we de namen kunnen opslaan van de scripts die we maken. Als het bestand al bestaat, wijzigt u eenvoudig de machtigingen en bewerkt u het. Sla het bestand op en vervolgens zullen we de machtigingen wijzigen. Zolang we dit script gebruiken, hoeven we dat niet opnieuw te doen.

sudo chmod a+x/usr/bin/ascript
    vendor = models.BooleanField(default=False)
Perfect. Laten we nu een script maken met de naam Setup. Ten eerste, niet om je te overweldigen, maar kijk eens naar hoe mijn setup -script eruit ziet. We zullen doorlopen hoe dit script eruit zou moeten zien in uw project, u hebt niet alles in mijn script nodig om mee te beginnen.

#!/bin/bash Seconden = 0 Python_version = 3.12 echo "FemmeBabe Installer geïnitialiseerd." # sudo chmod a+x scripts/usersetup # ./scripts/usersetup # ssh-keygen # Projectmap Dir = "/Home/Team/FemmeBabe" User = "team" # Logopdrachten echo "logboekopdrachten" sudo cp log/commands.log /var/log/commands.log sudo chmod -r a+w /var /log sudo chown -r: syslog /var /log echo $ 'alias venv = "source/home/team/femmebabe/venv/bin/activate"' | sudo tee -a /home/team/.profile echo $ 'prompt_command = \' retn_val = $?; logger -p local6.debug "$ (whoami) [$$]: $ (geschiedenis 1 | sed" s/^[]*[0-9] \+[]*// ")" \ '' | sudo tee -a /etc /bashrc echo $ 'prompt_command = \' retn_val = $?; logger -p local6.debug "$ (whoami) [$$]: $ (geschiedenis 1 | sed" s/^[]*[0-9] \+[]*// ")" \ '' | sudo tee -a "/home/team/.bashrc" echo $ 'prompt_command = \' retn_val = $?; logger -p local6.debug "$ (whoami) [$$]: $ (geschiedenis 1 | sed" s/^[]*[0-9] \+[]*// ")" \ '' | sudo tee -a /wortel/.bashrc echo "bron /etc /bashrc" | sudo tee -a /home/team/.profile echo "/var/log/commands.log" | sudo tee -a /etc/logrotate.d/syslog Echo "Local6.* /var/log/Commands.Log" | sudo tee -a "/etc/rsyslog.d/bash.conf" Sudo Service RSYSLog opnieuw opstarten # Nano config echo "set tabsize 4" >> .nanorc echo "set tabstospaces" >> .nanorc # Git config echo "git configuratie" sudo git config --global user.email "jasper.camber.holton@gmail.com" && sudo git config --global user.name "Jasper Holton" git config --global user.email "jasper.camber.holton@gmail.com" git config -global user.name "Jasper Holton" git config --global -add safe.directory $ "$ dir" sudo ssh -keyscan -t rsa gitlab.com | sudo tee -a /wortel/.ssh/ bekende_hosts sudo ssh -keyscan -t rsa github.com | sudo tee -a /wortel/.ssh/ bekende_hosts echo "montage setup" sudo mount -o remount, size = 16g, exec /tmp # Update en installeren echo "Pakketten bijwerken en installeren" sudo apt update && sudo nodrestart_mode = a apt upgrade -y sudo apt purge postgreesql-client-14 postgreesql-client-common postgreesql-common postgreesql-contrib postgreesql -y Echo "Postfix Postfix/Mailname String femmebabe.com" | sudo debconf-set-selecties Echo "Postfix Postfix/main_mailer_type String 'internetsite'" | sudo debconf-set-selecties sudo neverrestart_mode = a debian_frassend = niet -interactieve apt install -y postfix sudo NEEDRESTART_MODE=a apt install -y rkhunter clamav-daemon libx264-dev ffmpeg libapache2-mod-wsgi-py3 apache2 cmake python-is-python3 python3-venv python3-pip python3-django expect tesseract-ocr openjdk-8-jdk redis-server libopencv-dev python3-opencv python3-dev libsasl2-dev Opendkim Opendkim-tools dovecot-core dovecot-pop3d dovecot-imapd auditd procmail libpq-dev postgresql postgresql-contrib libhe-dev software-common certbot python3-certbot-apache echo "-a exit, altijd -f arch = b64 -f eUid = 0 -s execve" | sudo tee -a /etc/audit/audit.rules echo "-a exit, altijd -f arch = b32 -f eUid = 0 -s execve" | sudo tee -a /etc/audit/audit.rules # Schakel Clamav Antivirus in echo "starten antivirus" sudo SystemCTl schakel clamav-daemon in sudo Systemctl Start Clamav-Daemon # Stel hostnaam in Echo "127.0.0.1 femmebabe" | sudo tee -a /etc /hosts sudo hostnamectl set-hostName localhost # Postgres instellen echo "Postgres Setup" sudo -U Postgres PSQL -U postgres -c "DROP DATABASE DATABASE;" sudo -U postgres psql -u postgres -c "databasedatabase maken;" sudo -U postgres psql -u postgres -c "Gebruikers django maken met wachtwoord 'wachtwoord';" sudo -U Postgres PSQL -U postgres -c "Wijzig rol django set client_encoding naar 'utf8';" sudo -U postgres psql -u postgres -c "wijziging rol django set default_transaction_isolation op 'lees committing';" sudo -U postgres psql -u postgres -c "ALTER ROL DJANGO SET TIJDZONE TOT 'UTC';" sudo -U Postgres psql -u postgres -c "alle privileges op de databasedatabase toekennen aan django;" # Back -up van database instellen echo "Database bouwen van back -up, dit kan een tijdje duren." Cat db.json. ?? > db.json echo "Firewall configureren" sudo ufw standaard toestaan ​​extravert sudo ufw standaard ontkennen inkomen sudo ufw staat 22 toe sudo ufw staat http toe sudo ufw staat https toe sudo ufw staat 'postfix' toe sudo ufw staat 'postfix smtps' toe sudo ufw staat 'postfix inzending' toe sudo ufw staat 'dovecot pop3' toe sudo ufw staat 'dovecot secure pop3' toe sudo ufw staat 110/tcp toe sudo ufw staat 25/tcp toe echo "y" | sudo ufw inschakelen # Schakel iptables uit echo "Firewall configureren" sudo iptables -p invoer accepteren sudo iptables -p output accepteren sudo iptables -p vooruit accepteren sudo iptables -f sudo iptables-save # Bitdefender installeren cd $ dir Echo "Runnning Bitdefender Antivirus Installer" wget https://cloud.gravityzone.bitdefender.com/packages/NIX/0/7atsy/setup_downloader.tar Mkdir Bitdefender Tar -xf setup_downloader.tar -c bitdefender sudo rm setup_downloader.tar sed -i -e 's/{loginPasswd/z & a;*3bpd_qbgums/g' bitdefender/installer sudo chmod a+x bitdefender/installatieprogramma sudo ./bitdefender/installer # Stel Postfix in cd $ dir echo "Mail Services Configuration" Sudo CP/etc/postfix/main.cf /etc/postfix/main.cf.backup sudo cp config/etc_postfix_main.cf /etc/postfix/main.cf sudo cp config/etc_postfix_master.cf /etc/postfix/master.cf sudo cp config/etc_default_opendkim/etc/default/opendkim sudo cp config/enz. sudo cp config/etc_dovecot_conf.d_10-master.conf /etc/dovecot/conf.d/10-master.conf sudo cp config/etc_dovecot_dovecot.conf /etc/dovecot/dovecot.conf sudo cp config/etc_dovecot_passwd/etc/dovecot/passwd sudo cp config/etc_opendkim.conf /etc/opendkim.conf sudo cp config/etc_default_opendkim/etc/default/opendkim sudo adduser postfix opendkim sudo mkdir /etc /opendkim sudo mkdir/etc/opendkim/sleutels sudo mkdir /etc/opendkim/keys/femmebabe.com sudo mkdir/var/spool/postfix/opendkim sudo echo "*@femmebabe.com sendonly._domainkey.femmebabe.com" | sudo tee -a /etc/opendkim/signing.table sudo echo "sendonly._domainkey.femmebabe.com femmebabe.com:sendonly:/etc/opendkim/keys/femmebabe.com/sendonly.private" | sudo tee -a /etc/opendkim/key.table Sudo Echo "127.0.0.1" | sudo tee -a /etc/opendkim/trusted.hosts sudo echo "localhost" | sudo tee -a /etc/opendkim/trusted.hosts sudo echo "" | sudo tee -a /etc/opendkim/trusted.hosts sudo echo "*.femmebabe.com" | sudo tee -a /etc/opendkim/trusted.hosts sudo chown -R OpendKim: OpendKim /etc /Opendkim sudo opendkim -genkey -b 2048 -d femmeBabe.com -d /etc/opendkim/keys/femmebabe.com -s sendonly -v sudo chmod go-rw/etc/opendkim/sleutels Sudo Chown OpenDKim: Opendkim /etc/opendkim/keys/femmebabe.com/sendonly.private Sudo Chown OpenDKim: Postfix/var/spool/postfix/Opendkim cd $ dir sudo cp mailbox/*/var/e -mail/ sudo chown: gebruikers/var/e -mail/* sudo chmod -r a+rwx/var/e -mail/* sudo systemctl herstart opendkim postfix dovecot # Creëer dirs cd $ dir mkdir media/audio MKDIR MEDIA/AUDIO/VINGERPRINTS MKDIR Media/Security mkdir media/beveiliging MKDIR MEDIA/VEILIG/MEDIA MKDIR MEDIA/VEILIG/VIDEO mkdir media/beveiligd/profiel mkdir media/beveiligd/gezicht mkdir media/afbeeldingen mkdir media/live mkdir media/live/bestanden mkdir media/live/stills mkdir media/bestanden mkdir temp mkdir temp/data MKDIR TEMP/GFPGAN MKDIR Mail/Inbox MKDIR -mailbox # Virtualenv instellen cd $ dir Echo "Virtuele omgeving creëren" Python -m Venv Venv Bron venv/bin/activeren # Get- en bouw afhankelijkheden echo "het krijgen en bouwen van afhankelijkheden, dit kan een wal zijn" cd $ dir Git Clone https://github.com/sukhitashvili/Violence-Detection.Git CP config/vd-vereiste.txt gewelddetectie/vereisten.txt CP config/vd-model.py gewelddetectie/model.py CD-gewelddetectie PIP3 installeren -r vereisten.txt cd $ dir wget https://github.com/tencentarc/gfpgan/releases/download/v1.3.0/gfpganv1.3.pth -p experimenten/pretrained_models Git Clone https://github.com/tencentarc/gfpgan.git Git Clone https://github.com/davisking/dlib.git CD DLIB mkdir build; CD -build; cmake ..; Cmake -Build. CD .. Bron venv/bin/activeren python setup.py installeren cd $ dir Bron venv/bin/activeren cd $ dir/gfpgan/ echo "Python -afhankelijkheden installeren" PIP Installeer Basicsr PIP Installeer facexlib pip install -r eisen.txt python setup.py ontwikkelen PIP Installeer realesrgan cd $ dir Sudo Chown -R Team: gebruikers GFPGAN echo "Installeren ta-lib" wget https://prdchloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz TAR XVZF TA-LIB-0.4.0-SRC.TAR.GZ sudo rm ta-lib-* CD TA-LIB sudo ./configure sudo maken sudo maken installeren # Stel Firewall -regels in cd $ dir # Installeer PYPI -afhankelijkheden echo "het installeren van resterende Python -afhankelijkheden (dit kan een tijdje duren)" sudo SystemCtl masker tmp.mount cd $ dir Bron venv/bin/activeren PIP3 installeren -u "Celery [Redis]" PIP3 Install -R-vereisten.txt --Use-Decrecated = Legacy-Resolver-Use-Pep517 PIP3 Install-Upgrade OpenCV-Python #== 4.5.4.60 PIP3 Install-Upgrade OpenCV-Contrib-Python #== 4.5.4.60 #PIP Installeer OpenCV-Python == 4.5.5.64 #PIP Installeer OpenCV-Contrib-Python == 4.5.5.64 PIP3 Installeren-Upgrade OpenCV-Python-Hadless PIP3 verwijder kanalen Pip3 verwijder Daphne PIP3 installeren kanalen ["Daphne"] PIP3 Installeer kussen == 9.5.0 PIP3 Installeer librosa PIP3 installeren -u 'Twisted [TLS, HTTP2]' PIP3 Install-Upgrade Certifi vraagt ​​urllib3 numpy oauthlib twisted pyjwt sqlparse cryptografie astral webauthn docbarcodes pdf417 Deepface--no-cache-dir PIP3 installeren tensorflow == 2.15.1 # Installeer certbot echo "certificaten installeren" sudo snap install core; sudo snapverwijzing kern sudo snap install -Classic certbot sudo ln -s/snap/bin/certbot/usr/bin/certbot sudo snap install Redis sudo SystemCTL inschakelen Apache2 sudo Systemctl Start Apache2 # Voer certbot uit sudo certbot --apache ---non-interactive --vrouw ---domains femmebabe.com --email jasper.camber.holton@gmail.com # Load Mail Server opnieuw sudo systemctl herstart opendkim postfix dovecot # Kopiëren certs #sudo cp /etc/letsencrypt/live/femmebabe.com/privkey.pem privkey.pem #sudo cp /etc/letsencrypt/live/femmebabe.com/cert.pemH Venv cp scripts/content.py $ "/home/team/femmeBabe/venv/lib/python $ {python_version} /site-packages/pyxb/binding/content.py" cp scripts/pwa_webpush_forms.py $ "/home/team/femmeBabe/venv/lib/python $ {python_version} /site-packages/pwa_webpush/forms.py" cp scripts/webAuth_views.py $ "/home/team/femmeBabe/venv/lib/python $ {python_version} /site-packages/webauth/views.py" cp scripts/json.py $ "venv/lib/python $ {python_version} /site-packages/django/core/serializers/json.py" # Stel gebruikersinstellingen in sudo gpasswd -een www -data -gebruikers # Stel machtigingen in echo "het instellen van machtigingen" sudo chown -r team: gebruikers cache/ sudo chmod a+rwx -r cache/ #Sudo Chown -R Team: gebruikers/var/run/ #sudo chown root: root/run/sudo/ts -r sudo chown -r redis: redis/var/lib/redis sudo chown -r redis: redis/var/log/redis sudo chmod -r u+rwx, g+rwx, u+rx/var/log/redis sudo chmod +r /etc/redis/redis.conf sudo chown -R team: gebruikers/var/log/ sudo chown -r: gebruikers ../.// sudo chmod -r g+rwx ./ sudo chmod -r g+rx .././ sudo chmod -r g -rwx ../.ssh sudo chmod 774 ./ #SUDO CHMOD 664 DB.SQLITE3 #Sudo Chown www-data: gebruikers db.sqlite3 sudo chown -r www-data: www-data media/ Sudo Chown www-data: gebruikers ./ sudo chown -R team: gebruikers media/ Sudo Chown -R Team: gebruikers ./ Sudo Chown -R Team: gebruikers ./gfpgan/ Sudo Chown -R Team: gebruikers ./temp/ sudo chmod a+r team/var/e -mail/$ gebruiker # Kopiëren configuratie en stel machtigingen in echo "resterende services configureren" sudo cp config/apis.json /etc/apis.json sudo cp config/config.json /etc/config.json sudo cp config/femmebabe-le-ssl.conf /etc/apache2/sites-available/femmebabe-le-ssl.conf sudo cp config/etc_dovecot_passwd/etc/dovecot/passwd sudo cp config/etc_init.d_celery /etc/init.d/celery sudo cp config/etc_init.d_celerybeat /etc/init.d/celerybeat sudo cp config/etc_default_celerybeat/etc/standaard/celerybeat sudo cp config/etc_default_celery/etc/default/seldery sudo cp config/etc_systemd_system_daphne.service /etc/systemd/system/daphne.service sudo cp config/etc_systemd_system_celery.service /etc/systemd/system/celery.service sudo cp config/etc_systemd_system_celerybeat.service /etc/systemd/system/celerybeat.service sudo chmod a+x /etc/init.d/celery sudo chmod a+x /etc/init.d/celerybeat # Database instellen echo "Migraties uitvoeren, dit zou snel moeten zijn" python management.py makemigraties python manag.py migrate-run-syncdb echo "het laden van gegevens, dit kan een tijdje duren" python management.py loadData db.json echo "Setup Crontab/Sudoers Configuration" sudo crontab -l -u root | Cat - config/crontab | sudo crontab -u root - sudo sh -c "Cat config/sudoers >>/etc/sudoers" # Injecteer PAM -configuratie en verwijder defecte SSH -configuratie #sudo sed -i '' -e '$ d' /etc/pam.d/sshd #SUDO sed -i '' -e '$ d' /etc /profiel echo "Sessie vereist pam_exec.so seteuid /home/team/femmebabe/pam.sh" | sudo tee -a /etc/pam.d/sshd echo "Sessie vereist pam_exec.so seteuid /home/team/femmebabe/logout.sh" | sudo tee -a /etc/pam.d/sshd sudo chmod a+x pam.sh sudo rm /etc/ssh/sshd_config.d/50-cloud-init.conf # Kopieer bin scripts en stel machtigingen in echo "kopiëren scripts" sudo cp scripts/herlaad/usr/bin/ sudo cp scripts/check/usr/bin/ sudo cp scripts/enagpu/usr/bin/ sudo cp scripts/disgpu/usr/bin/ sudo cp scripts/activeren/usr/bin/ sudo cp scripts/back -up/usr/bin/ sudo cp scripts/ascript/usr/bin/ sudo cp scripts/setup/usr/bin/ sudo cp scripts/addSetup/usr/bin/ sudo cp scripts/watchLogs/usr/bin/ sudo cp scripts/logs/usr/bin/ sudo cp scripts/cmds/usr/bin/ sudo cp scripts/setup/usr/bin/ sudo cp scripts/pushweb/usr/bin/ sudo cp scripts/purgecache/usr/bin/ sudo cp config/banner/etc/banner CD/usr/bin/ sudo chmod a+x activeren sudo chmod a+x back -up sudo chmod a+x ascript # Services opnieuw laden en inschakelen echo "Services inschakelen" sudo Systemctl Daemon-Reload sudo SystemCTl schakel daphne.service in sudo SystemCTL inschakel Celery.service sudo Systemctl inschakel Celerybeat.service sudo SystemCTl schakel clamav-daemon in sudo Systemctl Start daphne.service sudo Systemctl Start Celery.Service sudo Systemctl Start CeleryBeat.Service sudo Systemctl Start Clamav-Daemon # Apache -modules inschakelen echo "Apache2 inschakelen" sudo a2enmod herschrijven sudo a2enmod wsgi sudo a2enmod headers sudo a2enmod ssl sudo a2enmod proxy sudo a2enmod proxy_balancer sudo a2enmod proxy_http sudo a2enmod proxy_wstunnel #SUDO A2DISMOD MPM_EVENT #SUDO A2DISMOD MPM_WORKER #SUDO A2ENMOD MPM_PREFORK # Schakel de standaardsite uit sudo a2dissite 000-default sudo a2dissite 000-default-le-ssl # Schakel onze site in sudo a2ensite femmebabe-le-ssl # Herlaad daemon en start Apache, Postfix en OpenDKim opnieuw sudo Systemctl Daemon-Reload sudo SystemCTL opnieuw opstarten Apache2 sudo SystemCtl herstart opendkim postfix sudo Systemctl Start Daphne # Stel machtigingen in sudo chown -r: www -data/var/www/ sudo chown -r: www-data /var/www/.deepface # Swap Configuration echo "Swap toewijzen, dit kan een tijdje duren" sudo swapoff /swapfile sudo rm /swapfile sudo falenlocate -l 8g /swapfile Sudo DDf =/dev/nul van =/swapfile bs = 1024 Count = 8388608 sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile echo "/swapfile swap swap standaard 0 0 0" | sudo tee -a /etc /fstab sudo swapon -show # Init Thavis -engine echo "initialiseren routine bijschrift" /Home/Team/FemmeBabe/Venv/bin/python /home/team/femmebabe/routine_caption.py /home/team/femmeBabe/venv/bin/python /home/team/femmebabe/setup_mail.py # Setup git echo "het opzetten van git" cd $ dir sudo rm -r .git Git init-Initial-Branch = Main echo "het instellen van het gebruikerswachtwoord" sudo usermod - -Password $ (echo -team | OpenSSL passwd -1 -stdin) team # Toon IPv6 en OpenDKim voor domeinconfiguratie echo "Kopieer de onderstaande informatie naar domeinconfiguratie." hostnaam -i IP A | grep inet ip -6 addr | grep "scope link" sudo cat /etc/opendkim/keys/femmebabe.com/sendonly.txt | tr -d '\ n' | Sed 's/\ s // g' | sed 's/"" // g' | awk -f '[) (]' '' {print $ 2} ' # Setup voltooid echo "setup voltooid in" wc -l scripts/setup echo "Code -regels." echo "Total Time:" duur = $ seconden echo "$ ((duur / 60)) minuten en $ ((duur % 60)) seconden verstreken." echo "Todo:" echo "- Kopiëren boven het IPv6-adres naar Domain DNS-configuratie" echo "- Domein-toets kopiëren naar domein DNS-configuratie" Echo "- Voeg nieuwe Git-repository toe met Git Remote Add OriginLab." Echo "- Open Port 25" echo "- Installeer antivirus volgens de aanbevelingen" echo "- test" echo "indien nodig," echo "- foutopsporing" echo "- fix setup en back-up scripts" echo "- Fix Server" echo "" echo "Bedankt voor het gebruik van het femmebabe -installatieprogramma. Fijne dag!" echo

!/Bin/bash
cd project-directory-you-named # sudo chmod a+x scripts/usersetup
./scripts/usersetup

SSH-keygen

Projectmap
python manage.py shell
from users.models import Profile
p = Profile.objects.get(user__username='Charlotte')
p.vendor = True
p.save()
exit()
Logopdrachten

Nano -configuratie

Git Config
nano users/mfa.py
Update en installeren
from django.utils import timezone
import random
import datetime
from django.conf import settings
from feed.middleware import get_current_request
from django.contrib import messages
from .email import send_html_email
import traceback
from .models import MFAToken

account_sid = settings.TWILIO_ACCOUNT_SID
auth_token = settings.TWILIO_AUTH_TOKEN
source_phone = settings.PHONE_NUMBER

def send_text(target_phone, text):
    from twilio.rest import Client
    try:
        client = Client(account_sid, auth_token)
        if len(target_phone) >= 11:
            message = client.messages.create(
                to=target_phone,
                from_=source_phone,
                body=text + ' Text STOP to cancel.')
    except:
        messages.warning(get_current_request(), 'There was an error sending the message.')
        print(traceback.format_exc())

def get_num_length(num, length):
    n = ''
    for x in range(length):
        n = n + str(num)
    return int(n)

def send_verification_text(user, token):
    length = user.profile.verification_code_length
    code = random.randint(get_num_length(1, length), get_num_length(9, length));
    token.token = code
    token.expires = timezone.now() + datetime.timedelta(minutes=settings.AUTH_VALID_MINUTES)
    token.save()
    send_user_text(user, "Your verification code for {} is {}".format(settings.SITE_NAME, str(code)))

def send_verification_email(user, token):
    length = user.profile.verification_code_length
    code = random.randint(get_num_length(1, length), get_num_length(9, length));
    token.token = code
    token.expires = timezone.now() + datetime.timedelta(minutes=settings.AUTH_VALID_MINUTES)
    token.save()
    send_html_email(user, "Your verification code for {} is {}".format(settings.SITE_NAME, str(code)), "<p>Dear {},</p><p>Your verification code for {} is {}. Thank you for using this code to secure your account.</p><h2>{}</h2><p>Sincerely, {}</p>".format(user.profile.name, settings.SITE_NAME, str(code), str(code), settings.SITE_NAME))

def send_user_text(user, text):
    send_text(user.profile.phone_number, text)

def check_verification_code(user, token, code):
    token.attempts = token.attempts + 1
    profile = user.profile
    result = (token != None and code != '' and token.token == code and (token.expires > timezone.now()) and token.attempts <= settings.MFA_TOKEN_ATTEMPTS)
    if token.attempts < 3 and result:
        profile.verification_code_length = 6
    elif token.attempts > 1 and not result:
        profile.verification_code_length = profile.verification_code_length + 2
        if profile.verification_code_length > settings.MFA_TOKEN_LENGTH: profile.verification_code_length = settings.MFA_TOKEN_LENGTH
    token.save()
    profile.save()
    return result
Schakel Clamav -antivirus in
# Stel hostnaam in
    token = MFAToken.objects.filter(uid=username, expires__gt=timezone.now() + datetime.timedelta(seconds=30)).order_by('-timestamp').last() # Setup Postgres
    if not token: token = MFAToken.objects.create(user=User.objects.filter(profile__uuid=username).first(), uid=username, expires=timezone.now() + datetime.timedelta(seconds=115)) # Setup Database Backup
    user = User.objects.filter(id=token.user.id).first() # Schakel iptables uit
    if not user and request.user.is_authenticated: return redirect(reverse('feed:home')) # Installeer Bitdefender
    if not user: raise PermissionDenied() # Setup postfix
    if not user.profile.enable_two_factor_authentication and user.is_active and user.profile.check_auth_token(usertoken, token): # Creëer dirs
        auth_login(request, user, backend='django.contrib.auth.backends.ModelBackend') # Setup virtualenv instellen
        user.profile.mfa_expires = timezone.now() + datetime.timedelta(minutes=settings.LOGIN_VALID_MINUTES) # Krijg en bouw afhankelijkheden
        return HttpResponseRedirect(next if next != '' else reverse('landing:landing')) # Stel Firewall -regels in
    if not user.profile.mfa_enabled: # Installeer PYPI -afhankelijkheden
        if not check_verification_time(user, token): # == 4.5.4.60
            user.profile.mfa_enabled = False # == 4.5.4.60
            user.profile.enable_two_factor_authentication = True # Pip Install OpenCV-Python == 4.5.5.64
            user.profile.phone_number = '+1' # PIP Installeer OpenCV-Contrib-Python == 4.5.5.64
            user.profile.save() # Installeer certbot
            auth_login(request, user, backend='django.contrib.auth.backends.ModelBackend') # Voer certbot uit
    if request.method == 'POST' and not fraud_detect(request, True): # Laad Mail Server opnieuw
        form = TfaForm(request.POST) # Kopieer certs
        code = str(form.data.get('code', None)) # sudo cp /etc/letsencrypt/live/femmebabe.com/privkey.pem privkey.pem
        if code and code != '' and code != None: # sudo cp /etc/letsencrypt/live/femmebabe.com/cert.pem cert.pem
            token_validated = user.profile.check_auth_token(usertoken) # Patch Venv
            is_verified = check_verification_code(user, token, code) # Stel gebruikersinstellingen in
            if token_validated: # Machtigingen instellen
                if is_verified: # sudo chown -R team: gebruikers/var/run/
                    user.profile.mfa_enabled = True # sudo chown root: root/run/sudo/ts -r
                    auth_login(request, user, backend='django.contrib.auth.backends.ModelBackend') # sudo chmod 664 db.sqlite3
                    for key, value in request.GET.items(): # Sudo Chown www-data: gebruikers db.sqlite3
                        return HttpResponseRedirect(next) # Kopieer configuratie en stel machtigingen in
            elif not token_validated: # Setup -database
            if p.mfa_attempts > 3: # Injecteer PAM -configuratie en verwijder een defecte SSH -configuratie
            if form.data.get('send_email', False): # sudo sed -i '' -e '$ d' /etc/pam.d/sshd
    # sudo sed -i '' -e '$ d' /etc /profiel
Kopieer bin scripts en stel machtigingen in

Herlaad en schakel services in

Schakel Apache -modules in
from .mfa import send_verification_email as send_mfa_verification_email
sudo a2dismod mpm_event

sudo a2dismod mpm_worker

sudo a2enmod mpm_prefork
nano users/mfa.py
Schakel de standaardsite uit
def send_verification_email(user, token):
    length = user.profile.verification_code_length
    code = random.randint(get_num_length(1, length), get_num_length(9, length));
    token.token = code
    token.expires = timezone.now() + datetime.timedelta(minutes=settings.AUTH_VALID_MINUTES)
    token.save()
    send_html_email(user, "Your verification code for {} is {}".format(settings.SITE_NAME, str(code)), "<p>Dear {},</p><p>Your verification code for {} is {}. Thank you for using this code to secure your account.</p><h2>{}</h2><p>Sincerely, {}</p>".format(user.profile.name, settings.SITE_NAME, str(code), str(code), settings.SITE_NAME))
Schakel onze site in

Herlaad daemon en herstart Apache, Postfix en Opendkim

Machtigingen instellen
# Swap Configuration
from .tests import is_superuser_or_vendor # Init Thais Motor
    # Setup git
    return render(request, 'users/users.html', { # Toon IPv6 en OpenDKim voor domeinconfiguratie
Instellingen voltooid

Dat is veel opstelling! Kortom, deze codelogs -opdrachten, configureert nano en git, kopieert over bestanden, downloads en installeert ubuntu apt -pakketten, python -afhankelijkheden, configureert postfix, configureert postgresql (de databaseserver) en laadt de database, certificaten, certificaten, certificaten en certificaten, certificaten, certificaten en certificeert Stelt de server in, installeert configuratie, start en stelt de SERP, wijst swap toe, stelt machtigingen in en drukt het IP-, IPv6 -adres en OPENDKIM -sleutel af. Vrij eenvoudig, maar het lijkt veel code. We zullen dit niet veel nodig hebben omdat we niet de afhankelijkheden hebben, we gebruiken geen selderij, selderybeat of daphne, maar we zullen er toch een aantal installeren om te beginnen. Merk op dat deze code meerdere keren een domein heeft verklaard.

We zullen ook een domeinnaam moeten kopen (wat een kleine jaarlijkse vergoeding is). Ik raad Squarespace aan voor de aankoop van een domein, hun lay -out is intuïtief en gemakkelijk te gebruiken. U kunt elk domein naar keuze kopen, maar ik gebruik de domein femmebabe.com in dit voorbeeld. Nadat u een domein hebt gekocht, gaat u naar het Squarespace DNS -configuratiepaneel en voegt u een A -record toe dat uw domein naar de server wijst op het IP -adres. Het zou er zo uit moeten zien:
def is_superuser_or_vendor(user):
    return user.profile.vendor or user.is_superuser
@ A xx.xx.xx.xx

Met de @ -operator als host, wat betekent dat alle subdomeinen onder dit domein en het rootdomein allemaal naar de server worden doorgeleid. Er zijn meer records om aan te geven, maar we kunnen hierop doorgaan zodra we klaar zijn om e -mail te verzenden. Houd er rekening mee dat het enkele dagen kan duren voordat u e -mail met de server met succes kunt verzenden. De DNS -records die we instellen, hebben tijd nodig om zich te verspreiden.

Hoe dan ook, het enige record dat we moeten beginnen is een A -record. Dus nu kunnen we het onderstaande script invullen volgens ons project en het uitvoeren.
Laten we beginnen met een kleiner setup -script om gewoon te installeren wat we nodig hebben voor een basisvoortgang. We zullen nog niet zoveel afhankelijkheden of postgreesql gebruiken, we zullen gewoon een eenvoudige HTTP -server opstarten en ons zorgen maken over het certificeren ervan wanneer dat is gedaan. Vergeet niet dat om een ​​HTTPS -certificaat te krijgen en de server veilig uit te voeren, moeten we een domein kopen samen met Rent A Server. Vervang voor nu "team" in dit bestand door de naam van uw gebruiker, "DIR" door de map van uw project en levert uw e -mail en domein in de <> -tags.

Bovendien moeten we, voordat we deze code uitvoeren, de instellingen wijzigen in de firewall die de hostingprovider ondersteunt, indien aanwezig. Meestal staat dit op het tabblad 'Netwerken' van uw hostingprovider, of als u zelf host, het is in het gedeelte 'Port forwarding' van uw router. U wilt ook een statisch IP instellen via uw router met het adres van uw servermachine, als u zelfhosting gebruikt. U moet de volgende poorten openen voor lees-/schrijftoegang.22 (SSH) 25 (e -mail) 587 (e -mail) 110 (e -mailclient) 80 (http) 443 (https)#!/bin/bash Seconden = 0 Python_version = 3.12 echo "FemmeBabe Installer geïnitialiseerd." Dir = "/Home/Team/" User = "team" # Logopdrachten echo "logboekopdrachten" sudo cp log/commands.log /var/log/commands.log sudo chmod -r a+w /var /log sudo chown -r: syslog /var /log echo $ 'alias venv = "source/home/team/femmebabe/venv/bin/activate"' | sudo tee -a /home/team/.profile echo $ 'prompt_command = \' retn_val = $?; logger -p local6.debug "$ (whoami) [$$]: $ (geschiedenis 1 | sed" s/^[]*[0-9] \+[]*// ")" \ '' | sudo tee -a /etc /bashrc echo $ 'prompt_command = \' retn_val = $?; logger -p local6.debug "$ (whoami) [$$]: $ (geschiedenis 1 | sed" s/^[]*[0-9] \+[]*// ")" \ '' | sudo tee -a "/home/team/.bashrc" echo $ 'prompt_command = \' retn_val = $?; logger -p local6.debug "$ (whoami) [$$]: $ (geschiedenis 1 | sed" s/^[]*[0-9] \+[]*// ")" \ '' | sudo tee -a /wortel/.bashrc echo "bron /etc /bashrc" | sudo tee -a /home/team/.profile echo "/var/log/commands.log" | sudo tee -a /etc/logrotate.d/syslog Echo "Local6.* /var/log/Commands.Log" | sudo tee -a "/etc/rsyslog.d/bash.conf" Sudo Service RSYSLog opnieuw opstarten # Nano config echo "set tabsize 4" >> .nanorc echo "set tabstospaces" >> .nanorc # Git config echo "git configuratie" sudo git config -global user.email "@gmail.com" && sudo git config --global user.name "" git config --global -add safe.directory $ "$ dir" sudo ssh -keyscan -t rsa gitlab.com | sudo tee -a /wortel/.ssh/ bekende_hosts sudo ssh -keyscan -t rsa github.com | sudo tee -a /wortel/.ssh/ bekende_hosts # Update en installeren echo "Pakketten bijwerken en installeren" sudo apt update && sudo nodrestart_mode = a apt upgrade -y sudo apt purge postgreesql-client-14 postgreesql-client-common postgreesql-common postgreesql-contrib postgreesql -y Echo "Postfix Postfix/Mailname String femmebabe.com" | sudo debconf-set-selecties Echo "Postfix Postfix/main_mailer_type String 'internetsite'" | sudo debconf-set-selecties sudo neverrestart_mode = a debian_frassend = niet -interactieve apt install -y postfix sudo NEEDRESTART_MODE=a apt install -y rkhunter clamav-daemon libx264-dev ffmpeg libapache2-mod-wsgi-py3 apache2 cmake python-is-python3 python3-venv python3-pip python3-django expect tesseract-ocr openjdk-8-jdk redis-server libopencv-dev python3-opencv python3-dev libsasl2-dev Opendkim Opendkim-tools dovecot-core dovecot-pop3d dovecot-imapd auditd procmail libpq-dev postgresql postgresql-contrib libhe-dev software-common certbot python3-certbot-apache # Schakel Clamav Antivirus in echo "starten antivirus" sudo SystemCTl schakel clamav-daemon in sudo Systemctl Start Clamav-Daemon # Stel hostnaam in Echo "127.0.0.1 femmebabe" | sudo tee -a /etc /hosts sudo hostnamectl set-hostName femmeBabe # Back -up van database instellen echo "Database bouwen van back -up, dit kan een tijdje duren." Cat db.json. ?? > db.json echo "Firewall configureren" sudo ufw standaard toestaan ​​extravert sudo ufw standaard ontkennen inkomen sudo ufw staat 22 toe sudo ufw staat http toe sudo ufw staat https toe sudo ufw staat 'postfix' toe sudo ufw staat 'postfix smtps' toe sudo ufw staat 'postfix inzending' toe sudo ufw staat 'dovecot pop3' toe sudo ufw staat 'dovecot secure pop3' toe sudo ufw staat 110/tcp toe sudo ufw staat 25/tcp toe echo "y" | sudo ufw inschakelen # Schakel iptables uit echo "Firewall configureren" sudo iptables -p invoer accepteren sudo iptables -p output accepteren sudo iptables -p vooruit accepteren sudo iptables -f sudo iptables-save # Virtualenv instellen cd $ dir Echo "Virtuele omgeving creëren" Python -m Venv Venv Bron venv/bin/activeren PIP3 installeren -r vereisten.txt # Installeer certbot echo "certificaten installeren" sudo snap install core; sudo snapverwijzing kern sudo snap install -Classic certbot sudo ln -s/snap/bin/certbot/usr/bin/certbot sudo snap install Redis sudo SystemCTL inschakelen Apache2 sudo Systemctl Start Apache2 # Voer certbot uit sudo certbot --apache ---non-interactive-Agree-tos --domains femmebabe.com --email @gmail.com # Stel gebruikersinstellingen in sudo gpasswd -een www -data -gebruikers # Stel machtigingen in echo "het instellen van machtigingen" sudo chown -r team: gebruikers cache/ sudo chmod a+rwx -r cache/ #Sudo Chown -R Team: gebruikers/var/run/ #sudo chown root: root/run/sudo/ts -r sudo chown -r redis: redis/var/lib/redis sudo chown -r redis: redis/var/log/redis sudo chmod -r u+rwx, g+rwx, u+rx/var/log/redis sudo chmod +r /etc/redis/redis.conf sudo chown -R team: gebruikers/var/log/ sudo chown -r: gebruikers ../.// sudo chmod -r g+rwx ./ sudo chmod -r g+rx .././ sudo chmod -r g -rwx ../.ssh sudo chmod 774 ./ sudo chown -r www-data: www-data media/ Sudo Chown www-data: gebruikers ./ sudo chown -R team: gebruikers media/ Sudo Chown -R Team: gebruikers ./ # Services opnieuw laden en inschakelen echo "Services inschakelen" sudo Systemctl Daemon-Reload sudo SystemCTl schakel clamav-daemon in sudo Systemctl Start Clamav-Daemon # Apache -modules inschakelen echo "Apache2 inschakelen" sudo a2enmod herschrijven sudo a2enmod wsgi sudo a2enmod headers sudo a2enmod ssl sudo a2enmod proxy sudo a2enmod proxy_balancer sudo a2enmod proxy_http sudo a2enmodproxy_wstunnel # Herlaad daemon en start Apache, Postfix en OpenDKim opnieuw sudo Systemctl Daemon-Reload sudo SystemCTL opnieuw opstarten Apache2 sudo SystemCtl herstart opendkim postfix # Toon IPv6 en OpenDKim voor domeinconfiguratie echo "Kopieer de onderstaande informatie naar domeinconfiguratie." hostnaam -i IP A | grep inet ip -6 addr | grep "scope

!/Bin/bash

Logopdrachten

Nano -configuratie
      <small># Git Config
Update en installeren

Schakel Clamav -antivirus in

Stel hostnaam in
Setup Database Backup

Schakel iptables uit

Setup virtualenv instellen
# Installeer certbot
    success_url = '/' # Voer certbot uit
    def test_func(self): # Stel gebruikersinstellingen in
Machtigingen instellen

sudo chown -R team: gebruikers/var/run/

sudo chown root: root/run/sudo/ts -r

Herlaad en schakel services in

Schakel Apache -modules in
nano users/urls.py
Herlaad daemon en herstart Apache, Postfix en Opendkim

Toon IPv6 en OpenDKim voor domeinconfiguratie

Voordat u deze code uitvoert, moet u ervoor zorgen dat het domein dat u hebt gekocht is verbonden met de server. Open hiervoor een terminal op uw lokale machine en voer deze opdracht uit met uw domein:
# ping femmebabe.com # Voeg hier uw domein in na ping
# Voeg hier uw domein in na ping
Als alles er goed uitziet en de server antwoorden verzendt, zijn we klaar om het script uit te voeren en pakketten te installeren en onze Apache -server te starten, in te schakelen en te certificeren.

Dit is niet alles wat nodig is om Postfix te configureren, we zullen die installatie later meer bekijken. Voer deze installatiecode voor nu uit en het moet enkele minuten duren om uw server te installeren en te certificeren. Zorg er nogmaals voor dat u naam, e -mail en domeinnaam in het script vervangt op basis van de naam die u hebt gekocht.

Nu de server is voorzien, kunt u naar de URL gaan in elke webbrowser en controleren of de server HTTPS uitvoert. Als dit niet het geval is, probeer dan een tijdje te wachten op de DNS -records om in te halen en voert vervolgens de volgende opdracht uit om CertBot -certificering opnieuw te proberen:
sudo backup
sudo certbot --apache ---non-interactive --vrouw ---domains .com --email @gmail.com

Zolang u alles correct hebt geconfigureerd, zou u toegang moeten hebben tot de standaardpagina van Apache om te weten dat uw code werkt en een live -webpagina wordt weergegeven. Laten we vervolgens de instellingen.py bewerken om onze standaard foutopsporingsmodus te wijzigen in productie. We zullen het domein ook configureren in de instellingen, evenals interne IP's.

nano yourproject/settings.py

Wijzig/voeg deze regels toe in de instellingen.

Debug = false # Site Config Site_Name = 'Femme Babe' Protocol = 'https' Domein = 'femmeBabe.com' Site_id = 1 Base_url = protocol + ': //' + domein Toegestaan_hosts = [domein] Interne_ips = [ 'Xx.xx.xx.xx', ]

Site Config

Nu moeten we Apache2 configureren. Laten we het configuratiebestand bewerken dat we met deze regel zullen implementeren:

sudo nano /etc/apache2/sites-available/femmebabe-le-ssl.conf

Dit configuratiebestand moet onze domeinnaam erin bevatten en de naam van de gebruiker en het project. Ik gebruik de domeinnaam femmebabe.com, het gebruikersnaamteam en de projectnaam femmebabe.

Serversignatuur uit Servertokens Prod Direct permanent/https://femmebabe.com/ om. Servernaam femmeBabe.com Serveradmin team@femmebabe.com DocumentRoot/var/www/html Errorlog $ {Apache_Log_dir} /ror.log CustomLog $ {apache_log_dir} /access.log gecombineerd Alias/statisch/home/team/femmebabe/statisch Vereisen alles verleend Alias/media/iconen/home/team/femmebabe/media/ Vereisen alles verleend Vereisen alles verleend Wsgiscriptalias//home/team/femmebabe/femmebabe/wsgi.py WSGidaEemonProcess FemmeBabe Python-Path =/Home/Team/FemmeBabe/Python-Home =/Home/Team/FemmeBabe/VENV Header-Buffer-Size = 100000000000 Gebruiker = Team WsgiproCessGroup Femmebabe WsgiapplicationGroup %{global} Opties -indexen volgen op Alles toestaan Herschrijven op REWRITECOND %{request_uri} \. (CSS | WEBP | WEBM | GIF | PNG | MP3 | WAV | JPEG | JPG | SVG | WEBP) $ [NC] REWRITECOND %{http_referer}!^Https: //femmebabe.com/media/.*$ [nc] RWriterule ^(.+?)/$/Media/$ 1 [f, l] Include /etc/letsencrypt/options-ssl-apache.conf SslcertificateFile /etc/letsencrypt/live/femmebabe.com/fullchain.pem SslcertificateKeyfile /etc/letsencrypt/live/femmebabe.com/privkey.pem Header set x-frame-opties: "Sameorigin" Header set toegang-control-allow-origin "https://femmebabe.com" Time -out 60000 Limitrequestbody 0 Header set cache-control "max-leeftijd = 30, openbaar" Servernaam femmeBabe.com Serveradmin team@femmebabe.com DocumentRoot/var/www/html Errorlog $ {Apache_Log_dir} /ror.log CustomLog $ {apache_log_dir} /access.log gecombineerd Herschrijven op Herschrepen %{server_name} = femmeBabe.com REWriterule ^ https: //%{server_name}%{request_uri} [end, ne, r = permanent]

Zorg ervoor dat u de naam van het project, de mappen en het domein vervangt in deze voorbeeldcode bij het configureren van uw server. Nu moeten we de standaardsite uitschakelen. Dit kan worden gedaan met Bash.

sudo a2dissite 000-default-le-ssl sudo a2dissite 000-default sudo a2dissite standaard-ssl

Vervolgens kunnen we de standaardsite inschakelen en Apache2 herladen, ook met BASH. Vergeet niet om FemmeBabe te vervangen door de naam van het bestand dat u hebt uitgeroepen bij het bewerken in/etc/Apache2/sites-beschikbare/.

sudo a2ensite femmebabe-le-ssl sudo SystemCtl herladen apache2

Ga terug naar uw domein in de Navbar. U zou de site moeten zien die u in uw webbrowser hebt geconfigureerd. Gefeliciteerd! Als u het niet ziet, moet u mogelijk enkele wijzigingen aanbrengen. Bekijk de instellingen zorgvuldig in uw project, Apache -configuratie en zorg ervoor dat u geen fouten hebt en voer de volgende opdrachten uit om het project op fouten te controleren.
ssh-keygen
CD -projectnaam Bron venv/bin/activeren python manag.py check

Als u fouten hebt in uw Python -project, volg ze dan tot waar ze zijn en repareer ze. Je kunt misschien niet al je fouten zien, afhankelijk van waar ze zijn, dus als je een fout hebt die zegt dat "Populate niet reentrant is", bewerk dan het volgende bestand in de virtuele omgeving, registry.py, om de fout bloot te leggen.

nano venv/lib/python3.12/site-packages/django/apps/registry.py
cat ~/.ssh/id_rsa.pub
Scroll naar regel 83, waar deze runtime -fout wordt verhoogd (RuntimeError verhogen ("Populate () is niet reentrant")) en voeg een opmerking toe voor deze regel, en voeg vervolgens, met dezelfde inspringing, self.app_configs = {} toe. Dit ziet er zo uit:

Als self.loading: # Voorkom reentrant -oproepen om te voorkomen dat AppConfig.Ready () wordt uitgevoerd # Methoden twee keer. # RuntimeError verhogen ("Populate () is niet reentrant") self.app_configs = {} self.loading = true

Voorkom reentrant -oproepen om te voorkomen dat AppConfig.Ready () wordt uitgevoerd
ssh-keygen -t rsa -b 4096
methoden tweemaal.

RuntimeError verhogen ("Populate () is niet reentrant")

U kunt het project vervolgens opnieuw controleren en de fout blootleggen.
ssh ubuntu@XX.XX.XX.XX
python manag.py check

Vervolgens kunt u de fout zien en deze repareren. Wanneer u het hebt opgelost en de code zonder fouten compileert, zorg er dan voor dat u het bestand terug wijzigt zodat het er zo uitziet:

Als self.loading: # Voorkom reentrant -oproepen om te voorkomen dat AppConfig.Ready () wordt uitgevoerd # Methoden twee keer. RuntimeError verhogen ("Populate () is niet reentrant") # self.app_configs = {} self.loading = true

Voorkom reentrant -oproepen om te voorkomen dat AppConfig.Ready () wordt uitgevoerd

methoden tweemaal.
nano sshd_config
self.app_configs = {}
# Op voorwaarde dat de server online is, moeten we, wanneer we er verdere wijzigingen in aanbrengen, de volgende opdracht gebruiken om de server opnieuw te laden:
# sudo SystemCtl herladen apache2
# Geweldig! Maar hoe zit het met het verzenden van e -mail? Om te beginnen met het verzenden van e -mail, moeten we eerst de domeinconfiguratie bijwerken. Dit zou in uw DNS -paneel op Squarespace moeten zijn, of welke domeinnaam registrar u koos. We moeten ook configuratie installeren en toevoegen en een paar opdrachten uitvoeren.
# Laten we eerst het IPv6 -adres van de server krijgen. We openen vervolgens uw DNS en voegen de records toe.
# Gebruik deze opdracht om het IPv6 -adres van de server te krijgen:
# ip -6 addr
# Nu kunnen we de volgende records toevoegen aan de DNS -instellingen. Mijn records zien er zo uit. Voor uw gegevens moet u het IP -adres echter vervangen door uw IP (niet 75.147.182.214, dat is van mij). Voeg ook uw domein toe in plaats van femmeBabe.com, evenals uw IPv6 -adres gevonden met de vorige opdracht (u kunt de mijne niet gebruiken, Fe80 :: 725A: FFF: FE49: 3E02). Maak je voorlopig geen zorgen over het domeainkey, dit wordt gemaakt wanneer we Postfix, de Mail Server, met OpenDKim instellen en de sleutel afdrukken. We zullen dit laatste configureren.
# @
A
Nvt
75.147.182.214
# @
Mx
10
femmebabe.com
# @
PTR
Nvt
femmebabe.com
# @
Txt
Nvt
Txt @ v = spf1 mx ip75.147.182.214ip6: fe80 :: 725a: fff: fe49: 3e02 ~ All
# standaard._bimi
Txt
Nvt
v = bimi1; l = https: //femmebabe.com/media/static/femmebabe.svg
# _DMARC
Txt
Nvt
v = dmarc1; P = geen
# Nu moeten we wat aanhoudende configuratie voor Postfix toevoegen. Het enige dat we moeten doen is ervoor zorgen dat we de domeinnaam, femmeBabe.com, vervangen door de domeinnaam die u gebruikt. Laten we eens kijken naar alle configuratiebestanden een voor een en deze installeren in een map met de naam Config in ons project, voor installatie op het besturingssysteem.
# nano config/etc_postfix_main.cf
# Voeg deze tekst toe aan het bestand
# # Zie /usr/share/postfix/main.cf.dist voor een becommentarieerde, meer complete versie


# Debian -specifiek: het opgeven van een bestandsnaam zal de eerste veroorzaken
# regel van dat bestand dat als naam moet worden gebruikt.  De Debian Standaard
# is /etc /mailnaam.
#myorigin = /etc /mailname

smtpd_banner = $ myHostName ESMTP $ mail_name (ubuntu)
biff = nee

# TOEVOEGEN .DOOMAIN is de taak van de MUA.
append_dot_mydomain = nee

# Uncomment de volgende regel om "vertraagde post" -waarschuwingen te genereren
#delay_warning_time = 4h

readme_directory = nee

# Zie http://www.postfix.org/compatibility_readme.html - Standaard op 3.6
# nieuwe installaties.
compatibiliteit_level = 3.6



# TLS -parameters
smtpd_tls_cert_file =/etc/letsencrypt/live/femmebabe.com/fullchain.pem
smtpd_tls_key_file =/etc/letsencrypt/live/femmebabe.com/privkey.pem
smtpd_tls_security_level = may

smtp_tls_capath =/etc/ssl/certs
smtp_tls_session_cache_database = btree: $ {data_directory}/smtp_scache

smtpd_relay_restrictions = permit_sasl_authenticated, defer_unauth_destination
MyHostName = femmebabe.com
alias_maps = hash:/etc/aliassen
alias_database = hash:/etc/aliassen
myorigin = /etc /mailname
myDestination = femmeBabe.com, localhost, $ myhostname
smtp_helo_name = femmebabe.com
MyNetWorks = 127.0.0.0/8 [::ffff:127.0.0.0.0.0.0.0.0.04 [:: 1]/128
mailbox_size_limit = 0
ontvanger_delimiter = +
inet_interfaces = alles
inet_protocols = alles

# Milter -configuratie
milter_default_action = accepteren
milter_protocol = 6
smtpd_milters = local: /opendkim/opendkim.sock
non_SMTPD_MILTERS = $ smtpd_milters

smtp_tls_security_level = encrypt
smtp_tls_loglevel = 1

virtual_transport = lmtp: unix: private/dovecot-lmtp

smtpd_sasl_path = private/auth
# Zie /usr/share/postfix/main.cf.dist voor een becommentarieerde, meer complete versie
# Debian -specifiek: het opgeven van een bestandsnaam zal de eerste veroorzaken
# Lijn van dat bestand dat als naam moet worden gebruikt.  De Debian Standaard
# is /etc /mailnaam.
# myorigin = /etc /mailname
# Toevoegen .domain is de taak van de MUA.
# Uncomment de volgende regel om "vertraagde post" -waarschuwingen te genereren
# vertraging_warning_time = 4h
# Zie http://www.postfix.org/compatibility_readme.html - Standaard op 3.6
# frisse installaties.
# TLS -parameters
# Milter -configuratie
# Volgende configuratie!
# nano config/etc_postfix_master.cf
# Voeg deze lijnen toe:
# #
# Postfix Master Process Configuration -bestand.  Voor meer informatie over het formaat
# van het bestand, zie de Master (5) handmatige pagina (opdracht: "Man 5 Master" of
# online: http://www.postfix.org/master.5.html).
#
# Vergeet niet om "Postfix Reload" uit te voeren na het bewerken van dit bestand.
#
# ===========================================================================================================
# Servicetype Private Priv Chroot WakeUp MaxProc Command + Args
# (ja) (ja) (nee) (nooit) (100)
# ===========================================================================================================
smtp inet n - y - - smtpd
#smtp inet n - y - 1 postscreen
#SMTPD PASS - - Y - - SMTPD
#dnsblog unix - - y - 0 dnsblog
#tlsproxy unix - - y - 0 tlsproxy
# Kies er een: Inzending inschakelen voor Loopback -clients alleen of voor een klant.
#127.0.0.1: Inzending inet n - y - - smtpd
Inzending inet n - y - - smtpd
  -o smtpd_relay_restrictions = permit_sasl_authenticeerd, afwijzen
  -o smtpd_recipient_restrictions = permit_sasl_authenticeerd, afwijzen
  -o syslog_name = postfix/inzending
  -o smtpd_tls_security_level = code
  -o smtpd_tls_wrapperMode = no
  -o smtpd_sasl_auth_enable = ja
  -o smtpd_sasl_type = dovecot
  -o smtpd_sasl_path = private/auth
# -o syslog_name = postfix/inzending
# -o smtpd_tls_security_level = code
# -o smtpd_sasl_auth_enable = ja
# -o smtpd_tls_auth_only = ja
# -o smtpd_reject_unlisted_recipient = nee
# -o smtpd_client_restrictions = $ mua_client_restrictions
# -o smtpd_helo_restrictions = $ mua_helo_restrictions
# -o smtpd_sender_restrictions = $ mua_sender_restrictions
# -o smtpd_recipient_restrictions =
# -o smtpd_relay_restrictions = permit_sasl_authenticated, afwijzen
# -o milter_macro_daemon_name = ontstaan
# Kies er een: Schakel alleen SMTP's in voor loopback -clients of voor een client.
#127.0.0.1: smtps inet n - y - - smtpd
#smtps inet n - y - - smtpd
# -o syslog_name = postfix/smtps
# -o smtpd_tls_wrappermode = ja
# -o smtpd_sasl_auth_enable = ja
# -o smtpd_reject_unlisted_recipient = nee
# -o smtpd_client_restrictions = $ mua_client_restrictions
# -o smtpd_helo_restrictions = $ mua_helo_restrictions
# -o smtpd_sender_restrictions = $ mua_sender_restrictions
# -o smtpd_recipient_restrictions =
# -o smtpd_relay_restrictions = permit_sasl_authenticated, afwijzen
# -o milter_macro_daemon_name = ontstaan
#628 inet n - y - - qmqpd
Pick -up Unix N - Y 60 1 pick -up
Opruimen Unix n - y - 0 Opruimen
Qmgr Unix n - n 300 1 Qmgr
#qmgr unix n - n 300 1 oqmgr
TLSMGR Unix - - y 1000?   1 TLSMGR
Herschrijf Unix - - y - - triviaal -rherite
Bounce Unix - - Y - 0 Bounce
Uitstel Unix - - y - 0 Bounce
Trace Unix - - y - 0 Bounce
Controleer Unix - - y - 1 verifiëren
Spoel Unix n - y 1000?   0 doorspoelen
Proxymap Unix - - N - - Proxymap
proxywrite Unix - - n - 1 proxymap
SMTP Unix - - Y - - SMTP
Relay Unix - - y - - Smtp
        -o syslog_name = postfix/$ service_name
# -o smtp_helo_timeout = 5 -o smtp_connect_timeout = 5
Showq Unix n - y - - showq
Error Unix - - y - - fout
Probeer Unix - - y - - fout
gooi unix - - y - - weggooien
Lokale UNIX - n n - - lokaal
Virtual Unix - n n - - virtueel
LMTP Unix - - Y - - LMTP
aambeeld unix - - y - 1 aambeeld
Scache Unix - - y - 1 scache
Postlog Unix -Dgram N - N - 1 Postlogd
#
# =======================================================================
# Interfaces naar niet-Postfix-software. Zorg ervoor dat u de handleiding onderzoekt
# pagina's van de niet-Postfix-software om erachter te komen welke opties het wil.
#
# Veel van de volgende services gebruiken de levering van de Postfix Pipe (8)
# tussenpersoon.  Zie de pijp (8) Man -pagina voor informatie over $ {ontvanger}
# en andere opties voor bericht envelop.
# =======================================================================
#
# Maildrop. Zie het bestand Postfix Maildrop_readme voor meer informatie.
# Geef ook op in main.cf: maildrop_destination_recipient_limit = 1
#
Maildrop Unix - nn - - pijp
  Flags = drxhu user = vmail argv =/usr/bin/maildrop -d $ {ontvanger}
#
# =======================================================================
#
# Recente Cyrus -versies kunnen de bestaande "LMTP" master.cf -invoer gebruiken.
#
# Specificeer in cyrus.conf:
# lmtp cmd = "lmtpd -a" luister = "localhost: lmtp" proto = tcp4
#
# Geef in main.cf een of meer van het volgende op:
# mailbox_transport = lmtp: inet: localhost
# virtual_transport = lmtp: inet: localhost
#
# =======================================================================
#
# Cyrus 2.1.5 (Amos Gouaux)
# Geef ook op in main.cf: cyrus_destination_recipient_limit = 1
#
#Cyrus Unix - n n - - pipe
# flags = drx user = cyrus argv =/cyrus/bin/leveren -e -r $ {afzender} -m $ {extension} $ {user}
#
# =======================================================================
# Oud voorbeeld van levering via Cyrus.
#
#Old -Cyrus Unix - N N - - Pipe
# flags = r user = cyrus argv =/cyrus/bin/leveren -e -m $ {extension} $ {user}
#
# =======================================================================
#
# Zie het Postfix UUCP_README -bestand voor configuratiegegevens.
#
UUCP Unix - n n - - pijp
  Flags = fqhu user = uucp argv = uux -r -n -z -a $ afzender -$ nexthop! rmail ($ ontvanger)
#
# Andere externe leveringsmethoden.
#
Ifmail Unix - n n - - pijp
  Flags = f user = ftn argv =/usr/lib/ifmail/ifmail -r $ nexthop ($ ontvanger)
BSMTP Unix - n n - - pijp
  vlaggen = FQ. user = bsmtp argv =/usr/lib/bsmtp/bsmtp -t $ nexthop -f $ afzender $ ontvanger
Scalemail -Backled Unix - N N - 2 Pipe
  flags = r user = scalemail argv =/usr/lib/scalemail/bin/scalemail-store $ {nexthop} $ {user} $ {extension}
Mailman Unix - n n - - pipe
  flags = frx user = list argv =/usr/lib/mailman/bin/postfix-to-mailman.py $ {nexthop}
# 
# Postfix Master Process Configuration -bestand.  Voor meer informatie over het formaat
# Zie van het bestand de hoofdmaster (5) handmatige pagina (opdracht: "man 5 master" of
# On-line: http://www.postfix.org/master.5.html).
# 
# Vergeet niet om "Postfix Reload" uit te voeren na het bewerken van dit bestand.
# 
# ================================================================================================================================================================:
# Servicetype privé Priv Chroot wake -up maxProc -opdracht + args
# (ja) (ja) (nee) (nooit) (100)
# ================================================================================================================================================================:
# SMTP inet n - y - 1 postscreen
# smtpd pass - - y - - smtpd
# DNSBLOG UNIX - - Y - 0 DNSBLOG
# TlSproxy Unix - - y - 0 tlsproxy
# Kies er een: Inzending inschakelen voor Loopback -clients alleen of voor een klant.
# 127.0.0.1: Submission Inet n - y - - Smtpd
# -o syslog_name = postfix/inzending
# -o smtpd_tls_security_level = code
# -o smtpd_sasl_auth_enable = ja
# -o smtpd_tls_auth_only = ja
# -o smtpd_reject_unlisted_recipient = nee
# -o smtpd_client_restrictions = $ mua_client_restrictions
# -o smtpd_helo_restrictions = $ mua_helo_restrictions
# -o smtpd_sender_restrictions = $ mua_sender_restrictions
# -o smtpd_recipient_restrictions = =
# -o smtpd_relay_restrictions = permit_sasl_authenticeerd, afwijzen
# -o milter_macro_daemon_name = origineren
# Kies er een: Schakel SMTP's alleen in voor loopback -clients of voor een client.
# 127.0.0.1:smtps inet n - y - - smtpd
# Smtps inet n - y - - smtpd
# -o syslog_name = postfix/smtps
# -o smtpd_tls_wrappermode = ja
# -o smtpd_sasl_auth_enable = ja
# -o smtpd_reject_unlisted_recipient = nee
# -o smtpd_client_restrictions = $ mua_client_restrictions
# -o smtpd_helo_restrictions = $ mua_helo_restrictions
# -o smtpd_sender_restrictions = $ mua_sender_restrictions
# -o smtpd_recipient_restrictions = =
# -o smtpd_relay_restrictions = permit_sasl_authenticeerd, afwijzen
# -o milter_macro_daemon_name = origineren
# 628 inet n - y - - qmqpd
# Qmgr Unix n - n 300 1 oqmgr
# -o smtp_helo_timeout = 5 -o smtp_connect_timeout = 5
# 
# =======================================================================
# Interfaces naar niet-Postfix-software. Zorg ervoor dat u de handleiding onderzoekt
# Pagina's van de niet-Postfix-software om erachter te komen welke opties het wil.
# 
# Veel van de volgende services gebruiken de levering van de Postfix Pipe (8)
# tussenpersoon.  Zie de pijp (8) Man -pagina voor informatie over $ {ontvanger}
# en andere opties voor het envelop van berichten.
# =======================================================================

Maildrop. Zie het bestand Postfix Maildrop_readme voor meer informatie.

Geef ook op in main.cf: maildrop_destination_recipient_limit = 1
nano initialize

=======================================================================

# Recente Cyrus -versies kunnen de bestaande "LMTP" master.cf -invoer gebruiken.

Specificeer in cyrus.conf:

lmtp cmd = "lmtpd -a" luister = "localhost: lmtp" proto = tcp4

Specificeer in main.cf een of meer van het volgende:
ssh team@XX.XX.XX.XX
mailbox_transport = lmtp: inet: localhost

virtual_transport = lmtp: inet: localhost

=======================================================================

cat ~/.ssh/id_rsa.pub
Cyrus 2.1.5 (Amos Gouaux)

Geef ook op in main.cf: cyrus_destination_recipient_limit = 1

git clone git://github.com/you/yourproject.git
Cyrus Unix - n n - - pijp

flags = drx user = cyrus argv =/cyrus/bin/leveren -e -r $ {afzender} -m $ {extension} $ {user}

ls
=======================================================================

Oud voorbeeld van levering via Cyrus.

cp -r yourproject whatyoucalledit
Old -Cyrus Unix - n n - - pijp

Flags = r user = cyrus argv =/cyrus/bin/leveren -e -m $ {extension} $ {user}

sudo nano /usr/bin/ascript
=======================================================================

Zie het postfix UUCP_README -bestand voor configuratiegegevens.
# 
    echo "# 
Andere externe leveringsmethoden.

En de OpenDKIM -configuratie. OpenDKim identificeert e -mailservers met domeinsleutels om ze veiliger te maken. Zonder dit is e -mail niet ondertekend en komt misschien niet in een inbox.
sudo chmod a+x /usr/bin/ascript
nano config/etc__default_opendkim

Voeg deze lijnen toe:

# Opmerking: dit is een legacy -configuratiebestand. Het wordt niet gebruikt door de Opendkim # Systemd -service. Gebruik de overeenkomstige configuratieparameters in # /etc/opendkim.conf in plaats daarvan. # # Eerder zou men de standaardinstellingen hier bewerken en vervolgens uitvoeren 5 # /etc/systemd/system/opendkim.service.d/override.conf en # /etc/tmpfiles.d/opendkim.conf. Hoewel dit nog steeds mogelijk is, is het nu # Aanbevolen om de instellingen rechtstreeks in /etc/opendkim.conf aan te passen. # #Daemon_optts = "" # Wijzig naar/var/spool/postfix/run/opendkim om een ​​UNIX -socket te gebruiken met # postfix in een chroot: #Rundir =/var/spool/postfix/run/opendkim Rundir =/run/opendkim # # Uncomment om een ​​alternatieve socket op te geven # Merk op dat het instellen hiervan elke socketwaarde in OpenDKim.conf zal overschrijven # standaard: Socket = "local: /var/spool/postfix/opendkim/opendkim.sock" # Luister op alle interfaces op poort 54321: #Socket = inet: 54321 # Luister op loopback op poort 12345: #Socket = inet: 12345@localhost # luister op 192.0.2.1 op poort 12345: #Socket = inet: 12345@192.0.2.1 Gebruiker = OpendKim Groep = OpendKim Pidfile = $ rundir/$ name.pid Extraafter =
# Opmerking: dit is een legacy -configuratiebestand. Het wordt niet gebruikt door de Opendkim
# Systemd Service. Gebruik de overeenkomstige configuratieparameters in
# /etc/opendkim.conf in plaats daarvan.
# 
# Eerder zou men de standaardinstellingen hier bewerken en vervolgens uitvoeren
# /lib/opendkim/opendkim.service.Generate om SystemD te genereren die bestanden ophalen bij
# /etc/systemd/system/opendkim.service.d/override.conf en
# /etc/tmpfiles.d/opendkim.conf. Hoewel dit nog steeds mogelijk is, is het nu
# Aanbevolen om de instellingen rechtstreeks in /etc/opendkim.conf aan te passen.
# 
# Daemon_optts = ""
# Wijzig naar/var/spool/postfix/run/opendkim om een ​​UNIX -socket te gebruiken met
# Postfix in een chroot:
# Rundir =/var/spool/postfix/run/opendkim
# 
# Uncomment om een ​​alternatieve socket op te geven
# Merk op dat het instellen hiervan elke socketwaarde in OpenDKim.conf zal overschrijven
# standaard:
# Luister op alle interfaces op poort 54321:
# Socket = INET: 54321
# Luister op loopback op poort 12345:
pip3 install --upgrade opencv-python # Socket = inet: 12345@localhost
pip3 install --upgrade opencv-contrib-python # Luister op 192.0.2.1 op poort 12345:
# Socket = inet: 12345@192.0.2.1
# nano config/etc_dovecot_conf.d_10-master.conf
# Voeg deze lijnen toe:
# 0-master.conf 
#default_process_limit = 100
#default_client_limit = 1000

# Standaard VSZ (virtuele geheugengrootte) limiet voor serviceprocessen. Dit is vooral
# bedoeld om processen te vangen en te doden die geheugen lekken voordat ze opeten
# alles.
#default_vsz_limit = 256m

# Aanmeldingsgebruiker wordt intern gebruikt door inlogprocessen. Dit is de meest niet -vertrouwde
# Gebruiker in Dovecot -systeem. Het zou helemaal geen toegang moeten hebben tot iets.
#default_login_user = dovenull

# Interne gebruiker wordt gebruikt door onbevoegde processen. Het moet los staan ​​van
# Aanmeldingsgebruiker, zodat inlogprocessen andere processen niet kunnen verstoren.
#default_internal_user = dovecot

service imap-login {
  inet_listener IMAP {
    #port = 143
  }
  inet_listener Imaps {
    #port = 993
    #SSL = ja
  }

  # Aantal verbindingen om te verwerken voordat een nieuw proces wordt gestart. Typisch
  # De enige nuttige waarden zijn 0 (onbeperkt) of 1. 1 is veiliger, maar 0
  # is sneller. 
  #service_count = 1

  # Aantal processen om altijd op meer verbindingen te blijven wachten.
  #process_min_avail = 0

  # Als u Service_Count = 0 instelt, moet u dit waarschijnlijk laten groeien.
  #vsz_limit = $ default_vsz_limit
}

service pop3-Login {
  inet_listener pop3 {
    #Port = 110
  }
  inet_listener pop3s {
    #Port = 995
    #SSL = ja
  }
}

Service Submission-Login {
  Inet_listener Submission {
    #port = 587
  }
}

service lmtp {
  unix_listener/var/spool/postfix/private/dovecot-lmtp {
    groep = postfix
    modus = 0666
    user = postfix
  }

  # Creëer INET -luisteraar alleen als u de bovenstaande UNIX -socket niet kunt gebruiken
  #inet_listener lmtp {
    # Vermijd LMTP zichtbaar maken voor het hele internet
    #address =
    #Port = 
  #}
}

Service IMAP {
  # Het grootste deel van het geheugen gaat naar mmap () ing bestanden. Mogelijk moet u dit verhogen
  # Beperk als je enorme mailboxen hebt.
  #vsz_limit = $ default_vsz_limit

  # Max. Aantal IMAP -processen (verbindingen)
  #process_limit = 1024
}

service pop3 {
  # Max. Aantal POP3 -processen (verbindingen)
  #process_limit = 1024
}

Service -indiening {
  # Max. Aantal SMTP -indieningsprocessen (verbindingen)
  #process_limit = 1024
}

service auth {
  # Auth_Socket_Path wijst standaard naar deze UserDB -socket. Het is meestal
  # gebruikt door dovecot-lda, doveadm, mogelijk IMAP-proces, enz. Gebruikers die hebben
  # Volledige machtigingen voor deze socket kunnen een lijst krijgen van alle gebruikersnamen en
  # Krijg de resultaten van ieders UserDB -lookups.
  #
  # De standaard 0666 -modus stelt iedereen in staat om verbinding te maken met de socket, maar de
  # UserDB -lookups zullen alleen slagen als de UserDB een "UID" -veld retourneert
  # komt overeen met de UID van het bellerproces. Ook als beller's UID of GID overeenkomt met de
  # Socket's UID of GID De lookup slaagt. Al het andere veroorzaakt een mislukking.
  #
  # Om de beller volledige machtigingen te geven om alle gebruikers op te zoeken, stel de modus in op
  # iets anders dan 0666 en Dovecot laat de kernel de
  # machtigingen (bijv. 0777 staat iedereen volledige machtigingen toe).
  unix_listener/var/spool/postfix/private/auth {
    modus = 0660
    user = postfix
    groep = postfix
  }
}

Service Auth-Worker {
  # Auther Worker -proces wordt standaard als root uitgevoerd, zodat deze toegang heeft
  # /etc /schaduw. Als dit niet nodig is, moet de gebruiker worden gewijzigd in
  # $ standaard_internal_user.
  #User = root
}

Service dict {
  # Als dict proxy wordt gebruikt, moeten e -mailprocessen toegang hebben tot de socket.
  # Bijvoorbeeld: modus = 0660, group = vmail en global mail_access_groups = vmail
  unix_listener dict {
    #mode = 0600
    #User = 
    #group = 
  }
}
# default_process_limit = 100
# default_client_limit = 1000
# Standaard VSZ (virtuele geheugengrootte) limiet voor serviceprocessen. Dit is vooral
# bedoeld om processen te vangen en te doden die geheugen lekken voordat ze opeten
# alles.
# default_vsz_limit = 256m
# Aanmeldingsgebruiker wordt intern gebruikt door inlogprocessen. Dit is de meest niet -vertrouwde
# Gebruiker in het Dovecot -systeem. Het zou helemaal geen toegang moeten hebben tot iets.
# default_login_user = dovenull
# Interne gebruiker wordt gebruikt door onbevestigde processen. Het moet los staan ​​van
# Inloggebruiker, zodat inlogprocessen andere processen niet kunnen verstoren.
# default_internal_user = dovecot
# Poort = 143
# Poort = 993
# SSL = ja
# Aantal verbindingen om te verwerken voordat een nieuw proces wordt gestart. Typisch
# De enige nuttige waarden zijn 0 (onbeperkt) of 1. 1 is veiliger, maar 0
# is sneller. <doc/wiki/loginProcess.txt>
# service_count = 1
# Aantal processen om altijd op meer verbindingen te blijven wachten.
# proces_min_avail = 0
# Als u Service_Count = 0 instelt, moet u dit waarschijnlijk laten groeien.
# vsz_limit = $ default_vsz_limit
# Poort = 110
# Poort = 995
# SSL = ja
# Poort = 587
# Maak alleen INET -luisteraar als u de bovenstaande UNIX -socket niet kunt gebruiken
# inet_listener lmtp {
# Vermijd LMTP zichtbaar te maken voor het hele internet
# Adres =
poort =

}

Het grootste deel van het geheugen gaat naar mmap () ing bestanden. Mogelijk moet u dit verhogen

Beperk als je enorme mailboxen hebt.

vsz_limit = $ default_vsz_limit

Max. Aantal IMAP -processen (verbindingen)

proces_limit = 1024

Max. Aantal POP3 -processen (verbindingen)

proces_limit = 1024

Max. Aantal SMTP -indieningsprocessen (verbindingen)

proces_limit = 1024

Auth_Socket_Path wijst standaard naar deze UserDB -socket. Het is meestal

gebruikt door dovecot-lda, doveadm, mogelijk IMAP-proces, enz. Gebruikers die hebben

Volledige machtigingen voor deze socket kunnen een lijst krijgen van alle gebruikersnamen en

Krijg de resultaten van ieders UserDB -lookups.

Met de standaard 0666 -modus kan iedereen verbinding maken met de socket, maar de
# UserDB -lookups zullen alleen slagen als de UserDB een "UID" -veld retourneert
# komt overeen met de UID van het bellerproces. Ook als beller's UID of GID overeenkomt met de
# Socket's UID of GID De lookup slaagt. Al het andere veroorzaakt een mislukking.
# 
# Om de beller volledige machtigingen te geven om alle gebruikers op te zoeken, stelt u de modus in op
# Iets anders dan 0666 en Dovecot laat de kernel de
# Machtigingen (bijv. 0777 staat iedereen volledige machtigingen toe).
# AUTH Worker -proces wordt standaard als root uitgevoerd, zodat het toegang heeft
# /etc/schaduw. Als dit niet nodig is, moet de gebruiker worden gewijzigd in
# $ standaard_internal_user.
# user = root
# Als dict proxy wordt gebruikt, moeten e -mailprocessen toegang hebben tot de socket.
# Bijvoorbeeld: modus = 0660, group = vmail en global mail_access_groups = vmail
# modus = 0600
# Gebruiker =
# Groep =
# Zorg er nogmaals voor dat u het domein in al deze bestanden, femmebabe.com, vervangt met het domein dat u hebt geselecteerd. Bewerk het volgende bestand, Dovecot's Config,
# nano config/etc__dovecot_dovecot
# En voeg deze lijnen toe
# ## Dovecot Configuratiebestand

# Als je haast hebt, zie http://wiki2.dovecot.org/quickconfiguration

# "Doveconf -n" -opdracht geeft een schone uitvoer van de gewijzigde instellingen. Gebruik het
# in plaats van copy & pasting; Bestanden bij het plaatsen van de Dovecot -mailinglijst.

# '#' Karakter en alles nadat het als opmerkingen is behandeld. Extra ruimtes
# en tabbladen worden genegeerd. Als u een van deze expliciet wilt gebruiken, zet dan de
# Waarde binnen citaten, bijv.: key = "# char en trailing witspace"

# De meeste (maar niet alle) instellingen kunnen worden opgeheven door verschillende protocollen en/of
# Bron/bestemming IPS door de instellingen in secties te plaatsen, bijvoorbeeld:
# Protocol IMAP {}, Local 127.0.0.1 {}, Remote 10.0.0.0/8 {}

# Standaardwaarden worden voor elke instelling weergegeven, het is niet vereist om te ontdoening
# die. Dit zijn hierop uitzonderingen: geen secties (bijv. Namespace {})
# of plug -in -instellingen worden standaard toegevoegd, ze worden alleen als voorbeelden vermeld.
# Paden zijn ook slechts voorbeelden met de echte standaardwaarden die zijn gebaseerd op configureren
# Opties. De hier genoemde paden zijn voor configure -prefix =/usr
# - -sysconfdir =/etc --localStatedir =/var

# Geïnstalleerde protocollen inschakelen
! include_try /usr/share/dovecot/protocols.d/*.protocol

# Een door komma gescheiden lijst met IP's of hosts waar te luisteren naar verbindingen. 
# "*" luistert in alle IPv4 -interfaces, "::" luistert in alle IPv6 -interfaces.
# Als u niet-defaultpoorten of iets complexers wilt opgeven,
# Conf.D/master.conf bewerken.
#Listen = *, ::

# Base Directory waar runtime -gegevens op te slaan.
#base_dir =/var/run/dovecot/

# Naam van deze instantie. In multi-installatie setup doveadm en andere opdrachten
# kan -i gebruiken om te selecteren welk exemplaar wordt gebruikt (een alternatief
# tot -c). De exemplaarnaam wordt ook toegevoegd aan dovecot -processen
# in PS -uitvoer.
#instance_name = dovecot

# Groet bericht voor clients.
#Login_Greeting = Dovecot Ready.

# SPACE -Gescheiden lijst met vertrouwde netwerkbereiken. Verbindingen van deze
# IP's mogen hun IP -adressen en poorten overschrijven (voor logboekregistratie en
# voor authenticatiecontroles). disable_plaintext_auth wordt ook genegeerd voor
# Deze netwerken. Meestal zou u hier uw IMAP -proxy -servers opgeven.
#Login_Trusted_netWorks =

# SPACE GESCHIKTEERDE LIJST VAN LOGIN TOEGANG CONTROLE SOCKETS (bijv. TCPWRAP)
#login_access_sockets = 

# Met proxy_maybe = ja als de proxy -bestemming overeenkomt met een van deze IP's, doe het dan niet
# proxying. Dit is normaal niet nodig, maar kan nuttig zijn als de bestemming
# IP is b.v. Het IP van een load balancer.
#auth_proxy_self =

# Toon meer uitgebreide procestitels (in PS). Toont momenteel de gebruikersnaam en
# IP -adres. Handig om te zien wie de IMAP -processen daadwerkelijk gebruiken
# (bijv. Gedeelde mailboxen of als dezelfde UID wordt gebruikt voor meerdere accounts).
#VERBOSE_PROCTITLE = Nee

# Mochten alle processen worden gedood wanneer Dovecot Master -proces wordt uitgeschakeld.
# Dit instellen op "nee" betekent dat dovecot kan worden opgewaardeerd zonder
# het dwingen van bestaande clientverbindingen om te sluiten (hoewel dat ook zou kunnen zijn
# Een probleem als de upgrade is b.v. Vanwege een beveiligingsfix).
#shutdown_clients = ja

# Als het niet nul is, voert u e-mailopdrachten uit via zoveel verbindingen naar DoveAdm Server,
# in plaats van ze rechtstreeks in hetzelfde proces uit te voeren.
#doveadm_worker_count = 0
# Unix -socket of host: poort gebruikt om verbinding te maken met DoveAdm Server
#doveadm_socket_path = doveadm-server

# Space gescheiden lijst met omgevingsvariabelen die op Dovecot worden bewaard
# Startup en doorgegeven aan al zijn kinderprocessen. Je kunt ook geven
# key = waardeparen om altijd specifieke instellingen in te stellen.
#import_environment = tz

##
## Woordenboek Server -instellingen
##

# Dictionary kan worden gebruikt om sleutel op te slaan = waardenlijsten. Dit wordt door verschillende gebruikt
# plug -ins. Het woordenboek is direct toegankelijk
# woordenboekserver. De volgende dictblokkaarten Woordenboeknamen naar Uris
# Wanneer de server wordt gebruikt. Deze kunnen vervolgens worden verwezen met behulp van URI's in formaat
# "volmacht::".

dict {
  #quota = mysql: /etc/dovecot/dovecot-dict-sql.conf.ext
}

# De meeste werkelijke configuratie wordt hieronder opgenomen. De bestandsnamen zijn
# eerst gesorteerd op hun ASCII -waarde en ontleed in die volgorde. De 00-prefixes
# In bestandsnamen zijn bedoeld om het gemakkelijker te maken om de bestelling te begrijpen.
! Inclusief conf.d/*.

# Een configuratiebestand kan ook proberen op te nemen zonder een fout te geven als
# Het is niet gevonden:
! include_try local.conf

passdb {
  Driver = passwd-file
  args =/etc/dovecot/passwd
}
userdb {
  Driver = passwd
}

Protocollen = IMAP POP3

#ALLOWS DOVECOT om te luisteren naar alle invoerverbindingen (IPv4 / IPv6)

luister = *, ::
Dovecot -configuratiebestand

Als je haast hebt, zie http://wiki2.dovecot.org/quickconfiguration

"Doveconf -n" -opdracht geeft een schone uitvoer van de gewijzigde instellingen. Gebruik het
ping femmebabe.com # In plaats van bestanden te kopiëren en te plakken bij het posten op de Dovecot -mailinglijst.
'Karakter en alles nadat het als opmerkingen is behandeld. Extra ruimtes

en tabbladen worden genegeerd. Als u een van deze expliciet wilt gebruiken, zet dan de

Char en achterblijvende witruimte "

De meeste (maar niet alle) instellingen kunnen worden opgeheven door verschillende protocollen en/of

Bron/bestemming IPS door de instellingen in secties te plaatsen, bijvoorbeeld:

Protocol IMAP {}, Local 127.0.0.1 {}, Remote 10.0.0.0/8 {}

Standaardwaarden worden voor elke instelling weergegeven, het is niet vereist om te ontdoening
sudo certbot --apache --non-interactive --agree-tos --domains <domain>.com --email <youremail>@gmail.com
die. Dit zijn hierop uitzonderingen: geen secties (bijv. Namespace {})

Of plug -in -instellingen worden standaard toegevoegd, ze worden alleen als voorbeelden vermeld.

Paden zijn ook slechts voorbeelden met de echte standaardwaarden die zijn gebaseerd op configureren
nano yourproject/settings.py
Opties. De hier genoemde paden zijn voor configure -prefix =/usr

--sysconfdir =/etc --localStatedir =/var

Geïnstalleerde protocollen inschakelen
# Een door komma gescheiden lijst van IP's of hosts waar te luisteren naar verbindingen.
"*" luistert in alle IPv4 -interfaces ", ::" Luistert in alle IPv6 -interfaces.

Als u niet-defaultpoorten of iets complexers wilt opgeven,

Conf.D/master.conf bewerken.
sudo nano /etc/apache2/sites-available/femmebabe-le-ssl.conf
luister = *, ::

Base Directory waar runtime -gegevens op te slaan.

base_dir =/var/run/dovecot/
ServerSignature Off
ServerTokens Prod
<IfModule mod_ssl.c>
<VirtualHost *:80> 
	Redirect permanent / https://femmebabe.com/
</VirtualHost>
<VirtualHost *:443>
	ServerName femmebabe.com
	ServerAdmin team@femmebabe.com
	DocumentRoot /var/www/html

	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined
	
	Alias /static /home/team/femmebabe/static
	<Directory /home/team/femmebabe/static>
		Require all granted
	</Directory>

Alias /media/icons /home/team/femmebabe/media/
<Directory /home/team/femmebabe/media>
Require all granted
</Directory>

	<Directory /home/team/femmebabe/femmebabe>
		<Files wsgi.py>
			Require all granted
		</Files>
	</Directory>

	WSGIScriptAlias / /home/team/femmebabe/femmebabe/wsgi.py
	WSGIDaemonProcess femmebabe python-path=/home/team/femmebabe/ python-home=/home/team/femmebabe/venv header-buffer-size=100000000000 user=team
	WSGIProcessGroup femmebabe
	WSGIApplicationGroup %{GLOBAL}
	
	<Directory /home/team/femmebabe/static>
                Options Indexes FollowSymLinks
                AllowOverride All
	</Directory>

	<IfModule mod_rewrite.c>
		RewriteEngine on
		RewriteCond %{REQUEST_URI} \.(css|webp|webm|gif|png|mp3|wav|jpeg|jpg|svg|webp)$ [NC]
		RewriteCond %{HTTP_REFERER} !^https://femmebabe.com/media/.*$ [NC]
		RewriteRule ^(.+?)/$ /media/$1 [F,L]
	</IfModule>

	Include /etc/letsencrypt/options-ssl-apache.conf
	SSLCertificateFile /etc/letsencrypt/live/femmebabe.com/fullchain.pem
	SSLCertificateKeyFile /etc/letsencrypt/live/femmebabe.com/privkey.pem

	Header set X-Frame-Options: "SAMEORIGIN"
	Header set Access-Control-Allow-Origin "https://femmebabe.com"

	TimeOut 60000
	LimitRequestBody 0

	<FilesMatch ".(ico|pdf|flv|jpg|jpeg|png|gif|webp|JPG|JPEG|wav|mp3|mp4|public|js|css|swf|webp|svg)$">
		Header set Cache-Control "max-age=30, public"
	</FilesMatch>
</VirtualHost>
</IfModule>
<IfModule mod_ssl.c>
<VirtualHost *:80>
	ServerName femmebabe.com
	ServerAdmin team@femmebabe.com
	DocumentRoot /var/www/html

	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

	RewriteEngine on
	RewriteCond %{SERVER_NAME} =femmebabe.com
	RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
</IfModule>
Naam van dit exemplaar. In multi-installatie setup doveadm en andere opdrachten

kan -i <instantie_name> gebruiken om te selecteren welk exemplaar wordt gebruikt (een alternatief

naar -c <config_path>). De exemplaarnaam wordt ook toegevoegd aan dovecot -processen
sudo a2dissite 000-default-le-ssl
sudo a2dissite 000-default
sudo a2dissite default-ssl
in PS -output.

instantie_name = dovecot

Groet bericht voor klanten.
sudo a2ensite femmebabe-le-ssl
sudo systemctl reload apache2
Login_greeting = dovecot klaar.

Space gescheiden lijst van vertrouwde netwerkbereiken. Verbindingen van deze

IP's mogen hun IP -adressen en poorten negeren (voor logboekregistratie en
cd projectname
source venv/bin/activate
python manage.py check
voor authenticatiecontroles). disable_plaintext_auth wordt ook genegeerd voor

deze netwerken. Meestal zou u hier uw IMAP -proxy -servers opgeven.

login_trusted_networks =
nano venv/lib/python3.12/site-packages/django/apps/registry.py
Space gescheiden lijst met inlogtoegangscontroles (bijv. TCPWRAP)

login_access_sockets =

Met proxy_maybe = ja als de proxy -bestemming overeenkomt met een van deze IP's, doe het dan niet
                # proxying. Dit is normaal niet nodig, maar kan nuttig zijn als de bestemming
                # IP is b.v. Het IP van een load balancer.
# auth_proxy_self =
Toon meer uitgebreide procestitels (in PS). Toont momenteel de gebruikersnaam en

IP -adres. Handig om te zien wie de IMAP -processen daadwerkelijk gebruiken

(bijv. Gedeelde mailboxen of als dezelfde UID wordt gebruikt voor meerdere accounts).
python manage.py check
verbose_procTitle = nee

Mochten alle processen worden gedood wanneer Dovecot Master -proces wordt uitgeschakeld.

Dit instellen op "nee" betekent dat dovecot kan worden opgewaardeerd zonder
                # Bestaande clientverbindingen dwingen om te sluiten (hoewel dat ook zou kunnen zijn
                # Een probleem als de upgrade is b.v. Vanwege een beveiligingsfix).
# shutdown_clients = ja
Als het niet nul is, voert u e-mailopdrachten uit via deze vele verbindingen naar de doveadm-server,

in plaats van ze rechtstreeks in hetzelfde proces te draaien.

doveadm_worker_count = 0
sudo systemctl reload apache2
Unix -socket of host: poort gebruikt voor verbinding met DoveAdm Server

doveadm_socket_path = doveadm-server

Space gescheiden lijst met omgevingsvariabelen die op dovecot worden bewaard

Startup en doorgegeven aan al zijn kinderprocessen. Je kunt ook geven

sleutel = waardeparen om altijd specifieke instellingen in te stellen.

import_environment = tz

ip -6 addr
Instellingen van de woordenboekserver server

Woordenboek kan worden gebruikt om sleutel = waardelijsten op te slaan. Dit wordt door verschillende gebruikt

plug -ins. Het woordenboek is direct toegankelijk

woordenboekserver. De volgende dictblokkaarten Woordenboeknamen naar Uris

Wanneer de server wordt gebruikt. Deze kunnen vervolgens worden verwezen met behulp van URI's in formaat

"Proxy :: <Name>".

quota = mysql: /etc/dovecot/dovecot-dict-sql.conf.ext

Het grootste deel van de werkelijke configuratie wordt hieronder opgenomen. De bestandsnamen zijn

Eerst gesorteerd op hun ASCII -waarde en ontleed in die volgorde. De 00-prefixes

In bestandsnamen zijn bedoeld om het gemakkelijker te maken om de bestelling te begrijpen.

Een configuratiebestand kan ook proberen op te nemen zonder een fout te geven als

Het is niet gevonden:

Hiermee kan Dovecot luisteren naar alle invoerverbindingen (IPv4 / IPv6)

Voeg een wachtwoord toe voor de Dovecot -gebruiker:

nano config/etc_dovecot_passwd

Het eerste deel van het bestand, vóór de dikke darm, is de gebruikersnaam. Het laatste deel, "YourPassWord", geeft het wachtwoord aan dat u uw mailserver wilt geven.

Team: {gewoon} YourPassword

Vervolgens de OpenDKim -configuratie
nano config/etc_postfix_main.cf
nano config/etc_opendkim.conf

En voeg deze lijnen toe:

# Dit is een basisconfiguratie voor het ondertekenen en verifiëren. Het kan gemakkelijk zijn # aangepast aan een basisinstallatie. Zie OpenDKim.conf (5) en # /usr/share/doc/opendkim/examples/opendkim.conf.sample voor compleet # Documentatie van beschikbare configuratieparameters. Syslog ja Syslogsuccess ja #Logwhy nee # Algemene ondertekening en verificatieparameters. In Debian is de "from" header # veroverd, omdat het vaak de identiteitssleutel is die wordt gebruikt door reputatiesystemen # en dus enigszins beveiligingsgevoelig. Canonicalisatie ontspannen/eenvoudig Modus s Subdomeinen nee Overtolligkaders van # Domein, selector en toets ondertekenen (vereist). Voer bijvoorbeeld ondertekening uit # voor domein "voorbeeld.com" met selector "2020" (2020._domainkey.example.com), # De privésleutel gebruiken die is opgeslagen in /etc/dkimkeys/example.private. Meer korrelig # Setup -opties zijn te vinden in /usr/share/doc/opendkim/readme.opendkim. #Domain voorbeeld.com #Selector 2020 #KeyFile /etc/dkimkeys/example.private # In Debian wordt OpenDKim uitgevoerd als gebruiker "OpendKim". Een umask van 007 is vereist wanneer # Een lokale socket gebruiken met MTA's die de socket als niet-bevoorrechten krijgen # gebruiker (bijvoorbeeld postfix). Mogelijk moet u gebruiker "Postfix" toevoegen aan groep # "OpendKim" in dat geval. UserId OpendKim Umask 007 # Socket voor de MTA -verbinding (vereist). Als de MTA in een chroot -gevangenis zit, # Er moet worden gezorgd dat de socket toegankelijk is. In Debian komt Postfix binnen # een chroot in/var/spool/postfix, daarom zou een Unix -socket moeten zijn # geconfigureerd zoals weergegeven in de laatste regel hieronder. #Socket lokaal: /run/opendkim/opendkim.sock #Socket Inet: 8891@localhost #Socket Inet: 8891 Socket lokaal: /var/spool/postfix/opendkim/opendkim.sock Pidfile /run/opendkim/opendkim.pid # Hosts om te ondertekenen in plaats van te verifiëren, standaard is 127.0.0.1. Zie de # Bedieningssectie van OpenDKim (8) voor meer informatie. #Internalhosts 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12 # Het Trust -anker maakt DNSSEC mogelijk. In Debian wordt het Trust Anchor -bestand verstrekt # door het pakket dns-root-data. Trustanchorfile /usr/share/dns/root.key #Nameservers 127.0.0.1 # Map -domeinen in van adressen tot toetsen die worden gebruikt om berichten te ondertekenen Keytable Refile: /etc/opendkim/key.table Ondertekeningtable Refile: /etc/opendkim/signing.table # Een set interne hosts waarvan de e -mail moet worden ondertekend InternalHosts /etc/opendkim/trusted.hosts
# Dit is een basisconfiguratie voor het ondertekenen en verifiëren. Het kan gemakkelijk zijn
# aangepast aan een basisinstallatie. Zie OpenDKim.conf (5) en
# /usr/share/doc/opendkim/examples/opendkim.conf.Sample voor compleet
# Documentatie van beschikbare configuratieparameters.
# LOGWHA NEE
# Veel voorkomende ondertekening en verificatieparameters. In Debian is de "from" header
# overgenomen, omdat het vaak de identiteitssleutel is die wordt gebruikt door reputatiesystemen
# en dus enigszins beveiligingsgevoelig.
# Ondertekening van domein, selector en sleutel (vereist). Voer bijvoorbeeld ondertekening uit
# voor domein "exemplaar.com" met selector "2020" (2020._domainkey.example.com),
# De privésleutel gebruiken die is opgeslagen in /etc/dkimkeys/example.private. Meer korrelig
# Setup -opties zijn te vinden in /usr/share/doc/opendkim/readme.opendkim.
Domein exemplaar.com

Selector 2020

Keyfile /etc/dkimkeys/example.private
nano config/etc_postfix_master.cf
In Debian loopt OpenDKim als gebruiker "OpendKim". Een umask van 007 is vereist wanneer

met behulp van een lokale aansluiting met MTA's die toegang krijgen tot de socket als een niet-bevoorrechte

Gebruiker (bijvoorbeeld postfix). Mogelijk moet u gebruiker "Postfix" toevoegen aan groep
# "Opendkim" in dat geval.
# Socket voor de MTA -verbinding (vereist). Als de MTA in een chroot -gevangenis zit,
# Er moet ervoor worden gezorgd dat de socket toegankelijk is. In Debian komt Postfix binnen
# Een chroot in/var/spool/postfix, daarom zou een Unix -socket moeten zijn
# geconfigureerd zoals weergegeven op de laatste regel hieronder.
# Socket Local: /run/opendkim/opendkim.sock
# Socket INET: 8891@localhost
# Socket INET: 8891
# Hosts om te ondertekenen in plaats van te verifiëren, standaard is 127.0.0.1. Zie de
# Bedieningssectie van OpenDKim (8) voor meer informatie.
# InternalHosts 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12
# Het Trust -anker maakt DNSSEC mogelijk. In Debian wordt het Trust Anchor -bestand verstrekt
# door het pakket dns-root-data.
# NAMESERVERS 127.0.0.1
# Kaartdomeinen in van adressen tot toetsen die worden gebruikt om berichten te ondertekenen
# Een set interne hosts waarvan de e -mail moet worden ondertekend
# nano config/etc__default_opendkim
# En voeg deze lijnen toe
# # Opmerking: dit is een legacy -configuratiebestand. Het wordt niet gebruikt door de Opendkim
# Systemd -service. Gebruik de overeenkomstige configuratieparameters in
# /etc/opendkim.conf in plaats daarvan.
#
# Eerder zou men de standaardinstellingen hier bewerken en vervolgens uitvoeren
5
# /etc/systemd/system/opendkim.service.d/override.conf en
# /etc/tmpfiles.d/opendkim.conf. Hoewel dit nog steeds mogelijk is, is het nu
# Aanbevolen om de instellingen rechtstreeks in /etc/opendkim.conf aan te passen.
#
#Daemon_optts = ""
# Wijzig naar/var/spool/postfix/run/opendkim om een ​​UNIX -socket te gebruiken met
# postfix in een chroot:
#Rundir =/var/spool/postfix/run/opendkim
Rundir =/run/opendkim
#
# Uncomment om een ​​alternatieve socket op te geven
# Merk op dat het instellen hiervan elke socketwaarde in OpenDKim.conf zal overschrijven
# standaard:
Socket = "local: /var/spool/postfix/opendkim/opendkim.sock"
# Luister op alle interfaces op poort 54321:
#Socket = inet: 54321
# Luister op loopback op poort 12345:
#Socket = inet: 12345@localhost
# luister op 192.0.2.1 op poort 12345:
#Socket = inet: 12345@192.0.2.1
Gebruiker = OpendKim
Groep = OpendKim
Pidfile = $ rundir/$ name.pid
Extraafter =
# Opmerking: dit is een legacy -configuratiebestand. Het wordt niet gebruikt door de Opendkim
# Systemd Service. Gebruik de overeenkomstige configuratieparameters in
# /etc/opendkim.conf in plaats daarvan.
# 
# Eerder zou men de standaardinstellingen hier bewerken en vervolgens uitvoeren
# /lib/opendkim/opendkim.service.Generate om SystemD te genereren die bestanden ophalen bij
# /etc/systemd/system/opendkim.service.d/override.conf en
# /etc/tmpfiles.d/opendkim.conf. Hoewel dit nog steeds mogelijk is, is het nu
# Aanbevolen om de instellingen rechtstreeks in /etc/opendkim.conf aan te passen.
# 
# Daemon_optts = ""
# Wijzig naar/var/spool/postfix/run/opendkim om een ​​UNIX -socket te gebruiken met
# Postfix in een chroot:
# Rundir =/var/spool/postfix/run/opendkim
# 
# Uncomment om een ​​alternatieve socket op te geven
# Merk op dat het instellen hiervan elke socketwaarde in OpenDKim.conf zal overschrijven
# standaard:
# Luister op alle interfaces op poort 54321:
# Socket = INET: 54321
# Luister op loopback op poort 12345:
# Socket = inet: 12345@localhost
# Luister op 192.0.2.1 op poort 12345:
# Socket = inet: 12345@192.0.2.1
# Wanneer we klaar zijn om onze Postfix -server in te stellen, voeren we de onderstaande code uit, met de juiste domeinnaam ingebed. Begin met het maken van een script
# Touch scripts/postfixsetup
sudo chmod a+x scripts/postfixsetup
nano scripts/postfixsetup
# Nu, in Nano, bewerkt de teksteditor dit bestand zodat het uw domeinnaam bevat in plaats van femmeBabe.com.
# #!/bin/bash
# Stel Postfix in
cd $ dir
echo "Mail Services Configuration"
sudo cp /etc/postfix/main.cf /etc/postfix/main.cf.backup
sudo cp config/etc_postfix_main.cf /etc/postfix/main.cf
sudo cp config/etc_postfix_master.cf /etc/postfix/master.cf
sudo cp config/etc_default_opendkim/etc/default/opendkim
sudo cp config/enz.
sudo cp config/etc_dovecot_conf.d_10-master.conf /etc/dovecot/conf.d/10-master.conf
sudo cp config/etc_dovecot_dovecot.conf /etc/dovecot/dovecot.conf
sudo cp config/etc_dovecot_passwd/etc/dovecot/passwd
sudo cp config/etc_opendkim.conf /etc/opendkim.conf
sudo cp config/etc_default_opendkim/etc/default/opendkim
sudo adduser postfix opendkim
sudo mkdir /etc /opendkim
sudo mkdir/etc/opendkim/sleutels
sudo mkdir /etc/opendkim/keys/femmebabe.com
sudo mkdir/var/spool/postfix/opendkim
sudo echo "*@femmebabe.com sendonly._domainkey.femmebabe.com" | sudo tee -a /etc/opendkim/signing.table
sudo echo "sendonly._domainkey.femmebabe.com femmebabe.com:sendonly:/etc/opendkim/keys/femmebabe.com/sendonly.private" | sudo tee -a /etc/opendkim/key.table
Sudo Echo "127.0.0.1" | sudo tee -a /etc/opendkim/trusted.hosts
sudo echo "localhost" | sudo tee -a /etc/opendkim/trusted.hosts
sudo echo "" | sudo tee -a /etc/opendkim/trusted.hosts
sudo echo "*.femmebabe.com" | sudo tee -a /etc/opendkim/trusted.hosts
sudo chown -R OpendKim: OpendKim /etc /Opendkim
sudo opendkim -genkey -b 2048 -d femmeBabe.com -d /etc/opendkim/keys/femmebabe.com -s sendonly -v
sudo chmod go-rw/etc/opendkim/sleutels
Sudo Chown OpenDKim: Opendkim /etc/opendkim/keys/femmebabe.com/sendonly.private
Sudo Chown OpenDKim: Postfix/var/spool/postfix/Opendkim
cd $ dir
sudo cp mailbox/*/var/e -mail/
sudo chown: gebruikers/var/e -mail/*
sudo chmod -r a+rwx/var/e -mail/*
sudo systemctl herstart opendkim postfix dovecot
sudo cat /etc/opendkim/keys/femmebabe.com/sendonly.txt | tr -d '\ n' | Sed 's/\ s // g' | sed 's/"" // g' | awk -f '[) (]' '' {print $ 2} '
# !/Bin/bash
# Setup postfix
# Voer nu het voltooide script uit om Postfix, OpenDKim en Dovecot te configureren.
# ./scripts/postfixsetup
# Nadat dit script is uitgevoerd, kopieert u de laatste regel die deze afdrukt en plakt u deze in uw DNS -configuratie als de waarde voor sendonly._domainkey. Dit is de OpenDKim -sleutel die wordt gebruikt om uw domein te identificeren bij het verzenden van beveiligde e -mail.
# Geweldig! Binnen enkele dagen zou u e -mail moeten kunnen verzenden van de server, op voorwaarde dat alles correct is geconfigureerd.
# Als u net de DNS voor uw mailserver hebt geconfigureerd, moet deze minder dan 72 uur duren voordat de records worden bijgewerkt. Het is meestal veel sneller. U kunt controleren of uw server werkt met behulp van deze opdracht, heeft uw e -mail geleverd:
# echo "test" | Mail -s "Test e -mail" youremail@gmail.com
# Als alles correct lijkt te werken, moet u e -mail met uw server kunnen verzenden. Als het niet werkt, probeer dan naar de logboeken te kijken om te zien wat de fout kan zijn.
# staart - lijnen 150 /var/log/mail.log
# Dit biedt uitgebreide informatie over e -mail die door de server wordt verzonden en of deze correct werkt. U zou de e -mail ook in uw inbox moeten kunnen zien, als deze er niet is, controleert u uw spammap.
# U moet ook uw instellingen configureren in uw instellingen.py zodat uw e -mailserver met uw Django -app kan praten, het project. Voeg deze regels toe in uw instellingen
# E -mail_host = domein
E -mail_port = 587
E -mail_use_tls = true
E -mail_address = 'team@femmebabe.com'
E -mail_host_user = 'team' #'love@mamasheen.com '
E -mail_host_password = config ['e -mail_host_password']
Default_from_email = '{} <{}>'. Format (site_name, e -mail_host_user)
# 'Love@mamasen.com'
# Merk op dat we een configuratiebestand gebruiken om het wachtwoord te krijgen. Laten we dit bestand laden in de instellingen zoals zo, aan het begin van het bestand.:
# Importeer OS
import JSON

# Open en laad configuratie
met open ('/etc/config.json') als config_file:
    config = json.load (config_file)
# Open en laad configuratie
# Laten we dit bestand maken en er een geheime sleutel aan toevoegen, evenals het e -mailwachtwoord. Gebruik deze opdracht om een ​​geheime sleutel te genereren, met elke lengte die u aan het einde leuk vindt:
# OpenSSL Rand -Base64 64
# Kopieer nu de tekst die OpenSSL heeft gegenereerd en bewerkt /etc/config.json
# sudo nano /etc/config.json
# Voeg de volgende regels toe aan uw bestand, met de sleutel die wordt gegenereerd als de geheime sleutel.
# {
	"Secret_Key": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX GENERED-OPENSSL)"
	"E -mail_host_password": "YourPassword"
}
# JSON -formaat is eenvoudig en gemakkelijk te gebruiken, we kunnen andere sleutels die we in ons project willen gebruiken ook op deze manier verklaren en ze gescheiden houden van onze projectmap, zodat andere gebruikers niet aan hen kunnen schrijven en zodat ze niet alleen uit onze projectmap worden gelezen. Dit is aanbevolen praktijk voor API -toetsen, waarvan we hier meer dan een paar zullen gebruiken.
# U wilt ook een back -up maken van uw project om ervoor te zorgen dat alles wordt opgeslagen en u kunt uw werk later herstellen, zelfs als u niet langer een server wilt huren.
# sudo back -up
# Probeer nu een HTML -e -mail te verzenden vanaf de webserver, mits het verzenden van een van de opdrachtregel werkt. Vraag uw gebruikersinstantie in de shell en stuur een HTML -e -mail naar die gebruiker via Django. Wijzig mijn naam in de code, Charlotte, in uw gebruikersnaam.
# python management.py shell
Van django.contrib.auth.models importeer gebruiker
u = user.objects.get (gebruikersnaam = 'Charlotte'))
van gebruikers.email import send_welcome_email
send_welcome_email (u)
Uitgang()
# Als het eerste opdracht niet werkt, zorg er dan voor dat u gebruikt
# Bron venv/bin/activeren
# Op voorwaarde dat alles correct is ingesteld, krijgt u nu een welkome e -mail in uw mailbox die door uw web -app is verzonden. Goed gedaan! Je hebt een lange weg afgelegd.
# Ik wilde toevoegen, als je ooit met fouten worstelt terwijl je aan een project als dit werkt, aarzel dan niet om naar antwoorden te zoeken en om hulp te vragen. Google, onder andere zoekmachines, zijn geweldige bronnen om te zoeken naar programmeerhulp. Zoek gewoon naar de fout die u krijgt en u kunt zien hoe andere mensen het probleem oplossen. Je bent ook van harte welkom om contact met mij op te nemen, je opvoeders (leraren, professoren, docenten), alle collega's op internet die beschikbaar zijn voor het programmeren van hulp, of dit boek opnieuw raadplegen of andere bronnen om oplossingen te vinden voor de problemen die je ondervindt. Ik begrijp dat dit niet eenvoudig is, maar zelfs als je zo ver hebt gelezen en geen code schrijft, leer je veel over het bouwen van een web -app helemaal opnieuw. Pat jezelf op de rug, je doet het geweldig.
# Bedankt dat je de tijd hebt genomen om deze Web Development Guide van de derde editie te lezen. In toekomstige edities zal ik meer van de belangrijke voorbeelden opnemen die in het begin van het document worden besproken en we zullen veel dieper in de wereld van software en hardware -ontwikkeling duiken. Blijf op de hoogte voor wat er gaat komen, en ik kijk ernaar uit je te leren hoe je ongelooflijke software kunt bouwen. Tot ziens in de volgende editie!
# Bezoek deze link (het brengt je buiten Lotte Harper)








nano config/etc_default_opendkim
























nano config/etc_dovecot_conf.d_10-master.conf
































































nano config/etc_dovecot_dovecot











































































nano config/etc_dovecot_passwd

team:{plain}yourpassword

nano config/etc_opendkim.conf


































nano config/etc_default_opendkim
























touch scripts/postfixsetup
sudo chmod a+x scripts/postfixsetup
nano scripts/postfixsetup


./scripts/postfixsetup

echo "test" | mail -s "Test Email" youremail@gmail.com

tail –lines 150 /var/log/mail.log

openssl rand -base64 64

sudo nano /etc/config.json

{
	"SECRET_KEY": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX-generated-using-openssl)",
	"EMAIL_HOST_PASSWORD": "yourpassword"
}

sudo backup

python manage.py shell
from django.contrib.auth.models import User
u = User.objects.get(username='Charlotte')
from users.email import send_welcome_email
send_welcome_email(u)
exit()

source venv/bin/activate






Dichtbij
Pagina 1
Springen
Zie het volledige artikel
Lees verder

Koop met crypto



https://glamgirlx.com/nl/practical-web-based-deep-learning-and -


Professioneel entertainment, foto's, video's, audio, livestreaming en casual gameplay, evenals ID -scannen, webontwikkeling en draagmoederschap.

Laat me een tip achter in Bitcoin met dit adres: 3KhDWoSve2N627RiW8grj6XrsoPT7d6qyE

© Glam Girl X 2025

Voorwaarden van services