Praktikal nga Nasukad sa Pagkat-on ug Kasiguruhan sa Web

Daisylitrato profile profile

Human Daisy

Praktikal nga Nasukad sa Pagkat-on ug Kasiguruhan sa Web Ikatulo nga edisyon Charlotte Harper Hulyo 3, 2024 Gi-update / nakabig sa Hunyo 3, 2025 Pasiuna: Ang mga konsiderasyon sa seguridad sa pagtukod sa software alang sa Web usa ka hinungdanon nga bahin sa plano ug pagpatay sa bisan unsang plano sa web samtang ang engineering usa ka prototype nga usa ka prototype nga kasaligan. Ang Dom (Document Object Markup), nga gipatuman kini sa HTML, Javascript, ug CSS nga nagpatuman sa mga proyekto ug gahum sa paggamit ug gahum sa paggamit ug gahum sa paggamit ug gahum sa paggamit ug gahum sa paggamit ug gahum sa paggamit ug gahum sa paggamit ug gahum sa paggamit ug kusog sa paggamit ug gahum sa paggamit ug gahum sa paggamit ug kinaiya, ug paghatag kadali sa paggamit ug gahum sa paggamit ug gahum sa paggamit ug gahum sa paggamit ug gahum sa paggamit ug gahum sa paggamit ug pamatasan, ug paghimog kadali sa paggamit ug gahum sa paggamit ug gahum sa paggamit ug gahum sa paggamit ug gahum sa paggamit ug gahum sa paggamit ug gahum sa paggamit ug gahum sa paggamit ug gahum sa paggamit ug gahum sa paggamit ug kusog sa paggamit ug kinaiya nga magamit sa kasagaran sa kasagaran Si Joe, ang katapusan nga tiggamit nga nagtan-aw sa pagpatay sa oras o pagkuha usa ka butang nga nahimo sa Internet, kasagaran sa usa ka touchscreen smartphone nga aparato. Most people wouldn't even know where to start when they want to build a website from scratch, they would tend to start on another person's website and build something limited in functionality, dependability, ease of use and especially creativity when they could have had all the latest powerful tools at their disposal in order to build something useful without wasting time pressing buttons, and especially wasting money paying for expensive subscriptions to software few people wanted to use anyway given it's limitations in kadali sa paggamit ug pagka-flexible. Kung ikaw adunay pipila ka minuto aron mabasa pinaagi sa kini nga libro ug mahibal-an kung unsa ang gusto nako nga itudlo kanimo, o pag-adto sa akong kaugalingon nga mga katuyoan ug pag-adto sa imong kaugalingon nga libro ug isulat ang imong gusto ug buhaton ang imong gusto ug buhaton ang imong gusto ug buhaton ang mga kinahanglanon sa imong mamiminaw. Bahin nako: Usa ako ka software developer nga adunay daghang kasinatian sa C / C ++, Java, Python, HTML, CSS ug JAVASSCHIP. Nagtukod ako mga website nga gusto sa mga tawo nga gamiton, gusto nga mobisita, ug bisan ang pagkaadik sa paggamit aron lamang sa pagkat-on, pag-usab sa oras, ug labing maayo, gibaligya nako ang software. If you had an idea as to exactly how you wanted a website to look and function, you were willing to support me so I can meet my own needs while I meet yours, and you are willing to cover the costs of running a website yourself, I would build you the next YouTube, TikTok, Twitter, Google, or even a high-tech security app only you can access. Imbis nga sulayan nga ibaligya nimo ang akong oras, nagtinguha ako sa pagpalit kanimo: Gusto ko nga makigsulti sa usa ka independente nga pag-develop sa App (Enderpreneur, nga adunay usa ka malampuson nga karera sa bisan unsang natad nga karera sa bisan unsang natad sa imong gusto. Ug tugoti ako nga klaro, ang edukasyon nga gihatag ko kanimo dili impormal. Mahimo ka nga moadto sa eskuylahan ug mahibal-an ang tanan niini nga adunay pormal nga edukasyon, o bisan pagbasa niini nga libro sa eskuylahan, kumpleto ang imong mga buluhaton, ug pag-ayo sa imong edukasyon ug hangyoon ka nga makompleto ang mga buluhaton. Dili ako ang imong propesor, mahimo nimong hunahunaon ako sama sa usa ka higala nga gusto nga mogiya kanimo ngadto sa usa ka karera nga gimaneho sa imong kaugalingon nga kalampusan. Ug dili ko ikaw gibaligya sa kalampusan, kinahanglan nimo nga paliton kini sa imong oras. Ang pagkat-on sa code adunay usa ka matulin nga kurbada sa pagkat-on ug dili gyud kadali, o bisan kung kini. Kinahanglan nimo nga magtrabaho kutob sa mahimo nimo ug magpadayon sa pagsulay ug mapakyas ug pagsulay pag-usab bisan kung ikaw nahigawad aron mahibal-an ang imong kaugalingon. Kana sa kinaiyahan sa code mismo. Ang code gipadagan sa usa ka tigpataliwala nga gidisenyo aron mahatagan ang mga mensahe sa sayup sa programmer, ug kini tudloan kanimo kung giunsa nimo pagkopya ang sayup sa imong search engine ug pagbasa sa mga ehemplo sa uban. Ug kinahanglan kong moingon, Dili kinahanglan nga ikaw dato kaayo, maalam, malampuson, o bisan ang detalye sa oriented o pag-organisar sa pagtukod sa usa ka app. Ang kompyuter nag-amping sa kana nga organisasyon alang kanimo. Kinahanglan nimo nga magpadayon sa pagsulay ug sayup, magpadayon sa pag-focus ug pag-ayo sa imong gibuhat, ug ikaw adunay usa ka malampuson nga karera sa kinatibuk-an sa imong gibuhat. Kinsa ako: Akong nahibal-an nga ang katapusan nga seksyon labi pa bahin sa pagkat-on ug ang imong mga pamaagi gikan sa kini nga libro. Kinsa man ako? Kana usa ka komplikado nga pangutana. Dili klaro ako sa akong kaugalingon, samtang nag-antus ako sa mga medikal nga kahimtang nga makapalisud alang kanako bisan sa code o isulat ang mga hagit sa pag-asoy sa akong kinabuhi sa pagpaila sa akong kaugalingon. Sa laktud, kung gibasa nimo kini nga libro, gidala nimo kini sa balay tungod kay gipunting mo kini ug naghunahuna nga kini mapuslanon, o kung ikaw ang sama sa hunahuna nga gusto nimo nga molampos sa tanan nga imong gibuhat. Ako usaengineer myself, a software developer, and a student, and I am writing this book for other students who want to make their lives easier by having a handbook of the software they need making their lives easier by giving examples to copy that fit together like a big puzzle into a working, useful, large, functional, cohesive, and engaging app that can drive success no matter the line of business. Labaw, kini ang akong buhaton: Nagtukod ako mga app aron matabangan ang akong kaugalingon ug ang ubang mga tawo molampos. Usa usab ako ka tagsulat, bisan kung kini ang akong una nga publikasyon nga gitinguha ko nga makompleto aron ibutang ang akong portfolio nga maghiusa sa usa ka mapuslanon nga dokumento, ug ako usa ka artista usab. Moangkon ko kini kanimo, lahi ako sa usa ka katingad-an nga tawo. Dili ako perpekto, nagdagan ako sa Balaod bisan ang pagdala kanako sa pagbiya sa mga kolehiyo ug unibersidad ug pagbiya sa mga estado aron sulayan ang akong kaugalingon nga adunay dugang nga kalampusan. Ako usa ka babaye nga natawo, nagsul-ob ako sa makeup, pagkuha mga litrato sa akong kaugalingon, magsul-ob og mga sinina ug uban pang mga babaye nga babaye, ug ako nagpabilin nga nahibal-an sa akong kaugalingon ingon usa ka babaye sa kinaiyahan. Adunay ako mga isyu sa ubang mga tawo kaniadto nga mosangput sa mga pakigbisog sa pagsulat ug pagtukod sa mga webapps, ug nangayo ako pasaylo nga wala na nako makuha kini nga libro sa imong mga kamot sa madali: Kinahanglan nimo kini. Gusto nimo nga magbasa ug magsulat sa code nga sama sa akoa ug nagtrabaho sama sa akoa ug naghimo sa parehas nga butang apan labi ka maayo ang imong pag-angkon sa imong kaugalingon aron mahimo ang imong libro nga kinahanglan nga magmalampuson sa imong kinabuhi. Ako adunay tanan nga mga isyu sa mga isyu nga nagtubo, kondisyon sa kahimsog, mga doktor, media, ug ang akong code sa pagkabahinbahin sa kalibutan. Bisan pa, kini nga libro usa ka butang nga akong nahunahunaan, akong masuso, akong panginabuhi, ug akong panginabuhi, busa gipabilhan ko ang imong konsiderasyon sa imong pag-adto sa teksto sa balay ug pag-ayo sa pagkat-on gikan kanako. Palihug hinumdumi ako dili ako hingpit, kini nga libro adunay mga sayup, mga pagbag-o, ug mga bag-ong edisyon, ug kinahanglan nimo nga hunahunaon ang imong makatarunganon nga kasinatian sa akong pagsulat. Hibal-i usab nga gipasabut nako nga maayo alang kanimo bisan kung nag-atubang ka mga hagit sa pagsulat. Think about it like this: When you can just rent a computer system to do anything you can possibly imagine in the digital space, store all the information you encounter, analyze and organize it, and come to understand it, you will inevitably encounter difficulties with the information you are ingesting and even publishing. Gisulti ko kini kanimo tungod kay nakasinati ako sa parehas nga mga kalisud. Gamita kini nga libro sa imong kaugalingon nga peligro, pagtrabaho uban sa imong komunidad ug mga komunidad nga magamit kanimo sa usa ka luwas nga paagi, ug kung giunsa ko kini madala sa usa ka luwas nga dalan diin kita molihok, sa Internet. Tingali dili ka pamilyar sa kung kinsa ako uban ang pipila lang nga mga pulong, apan gidasig ko ikaw sa pagbasa, mailhan mo ako samtang nagpadayon ka sa pagbasa ug pagsabut sa imong kaugalingon nga mga proyekto aron makompleto ang imong trabaho. Wala'y homwork sa kini nga libro, basta ang imong mga propesor o magtutudlo wala magtudlo kanimo, apan gidasig ko ikaw sa pagtukod sa usa ka Portfolio sa imong nahibal-an kung giunsa nimo magamit ang imong nakat-unan. My capstone project is the basis for most of what you will read in this book, as it incorporates code from my previous projects, code I have created and learned to write methodically by hand, and a wide range of ideas and tips that have helped me succeed to the point where I can spin up a simple app that is fully featured and looks and behaves like a popular app you might see your friend or family using, on the internet, advertised to you, or in the news. Unsa kini nga libro: Kini nga libro usa ka panudlo pinaagi sa panig-ingnan. You can find code here, instructions for how to learn to code, information on debugging code and fixing errors, troubleshooting steps, instructions on how to back up and save your code, re-deploy if anyone breaks your code, secure your code, deploy your code, build interactive websites that are entertaining, engaging, and addictive, and you will get a sense of who I am, why this is important, and how to portray yourself, your app and company image, as well as the Software nga imong gitukod sa hingpit nga labing maayo nga kahayag aron mahimong labing madanihon kutob sa mahimo sa imong mga tiggamit sa katapusan, ang mga bisita sa imong website. Niini nga libro, ipakita nako ang daghang mga pananglitan sa disenyo sa software nga adunay usa ka pagtuon sa web ingon usa ka plataporma ingon man seguridad. Atong sugdan ang pagkat-onkasilyas
Praktikal nga Nasukad sa Pagkat-on ug Kasiguruhan sa Web

Per exemple, aprenentatge profund i seguretat basat en la web per exemple Tercera edició Charlotte Harper 3 de juliol de 2024 Actualitzat/convertit el 3 de juny de 2025

Pròleg:

Les consideracions de seguretat en la creació de programari per a la web són una part important del pla i l'execució de qualsevol desenvolupador web mentre s'enginyen un prototip que sigui fiable, estable i útil amb finalitats pràctiques. The DOM (Document Object Markup), with it's implementation of HTML, JavaScript, and CSS as well as backend software implementing Python, C/C++, Java and bash, give web developers the freedom and power to create a wide variety of projects that express creativity, provide ease of use and functionality, portray humility and character, and provide ease of use as well as convenience and important services that are all attractive to the average Joe, the L'usuari final que busca matar temps o fer alguna cosa a Internet, normalment en un dispositiu de telèfon intel·ligent de pantalla tàctil. La majoria de la gent ni tan sols sabria per on començar quan volen construir un lloc web des de zero, tendirien a començar al lloc web d'una altra persona i a crear alguna cosa limitada en funcionalitat, fiabilitat, facilitat d'ús i sobretot creativitat quan podrien haver tingut totes les darreres eines potents a la seva disposició per tal de crear alguna cosa útil sense perdre els botons de pressió de temps i, sobretot, malgastar diners per pagar subscripcions costoses a programari que poques persones volien utilitzar de totes maneres donades en les limitacions en l'ús i la flexibilitat. Si teniu uns minuts per llegir aquest llibre i aprendre el que vull ensenyar, o fins i tot parlar amb mi personalment sobre els vostres objectius i obtenir algunes orientacions en la direcció correcta i esteu motivats a aprendre a codificar i escriure el vostre propi programari, feu aquest llibre a casa i deixa de banda un temps per aprendre a crear la propera aplicació web influent, potent, racionalitzada i important, un lloc web que és tot i que fa exactament el que voleu que vulgueu.

Sobre mi: Sóc desenvolupador de programari amb una àmplia experiència en C/C ++, Java, Python, HTML, CSS i JavaScript. Construeixo llocs web que la gent vol utilitzar, vull visitar i fins i tot em fa addicte a utilitzar només per aprendre, recrear i matar el temps, i el més important, venc programari. Si teníeu una idea de com volíeu que un lloc web es fixés i funcionés, estaves disposat a donar-me suport per poder satisfer les meves necessitats mentre em trobo amb les vostres, i esteu disposats a cobrir els costos d'executar un lloc web, us crearia el proper YouTube, Tiktok, Twitter, Google o fins i tot una aplicació de seguretat d'alta tecnologia a la qual només podeu accedir. En lloc d'intentar vendre't el meu temps, estic intentant comprar el teu: vull parlar -te per crear una aplicació (lloc web) amb la informació que ja existeix i ensenyar -te el que necessites per ser un desenvolupador de programari independent, empresari, liderant una carrera d'èxit en qualsevol camp que desitgis. I deixeu -me clar, l'educació que us dono serà informal. Podríeu anar a l'escola i aprendre tot això amb una educació formal, o fins i tot llegir aquest llibre a l'escola, completar les vostres tasques i treure molt de la vostra educació, però no us posaré formalment al seient calent i us demanaré que realitzeu tasques. No sóc el vostre professor, podeu pensar en mi com un amic que vol guiar -vos cap a una carrera impulsada pel vostre propi èxit personal. I tampoc us venc èxit, haureu de comprar -lo amb el vostre temps. L'aprenentatge de codificació té una forta corba d'aprenentatge i mai va ser fàcil, ni tan sols se suposa que ho fos. Heu de treballar el màxim que pugueu i continuar provant i proveu -ho i torneu -ho a provar fins i tot quan us frustreu per aprendre i crear aplicacions. Això és de la naturalesa del propi codi. El codi està dirigit per un compilador dissenyat per donar als missatges d'error del programador i això us ensenyarà a codificar, fins i tot si simplement esteu copiant l'error al vostre motor de cerca i llegiu exemples d'altres persones. I he de dir que no cal que siguis extremadament ric, intel·ligent, reeixit o fins i tot de detall orientat o organitzat per crear una aplicació. L'ordinador s'ocupa d'aquesta organització per a vosaltres. Només heu de perseverar a través de la prova i l'error, mantenir l'enfocament i treballar dur en el que feu, i tindreu una carrera molt reeixida durant tot el que feu.

Qui sóc: M'adono que l'última secció va tractar més d'aprendre i fer -ne un camí d'aquest llibre. Qui sóc exactament? Aquesta és una pregunta complicada. Jo mateix no estic clar, ja que pateixo condicions mèdiques que poden dificultar -me fins i tot codificar o escriure aquest llibre de vegades, alhora que presento reptes amb problemes de socialització i identitat que dificulten la meva vida a l'hora d'introduir -me. En resum, si esteu llegint aquest llibre, el vau portar a casa perquè el vau passar i heu pensat que era útil, o fins i tot si només heu llegit tan lluny, per a vosaltres sóc una persona semblant que vol veure que triomfeu en tot el que feu. Sóc un enginyer jo mateix, un desenvolupador de programari i un estudiant, i escric aquest llibre per a altres estudiants que vulguin facilitar la seva vida tenint un manual del programari que necessiten facilitar la seva vida donant exemples per copiar que s'ajusten com un gran trencaclosques en una aplicació treballadora, útil, gran, funcional, cohesionada i atractiva que pugui impulsar l'èxit sense importar la línia de negocis. En gran mesura, això és el que faig: creo aplicacions per ajudar -me a mi i a les altres persones a tenir èxit. Jo també sóc un autor, tot i que aquesta és la meva primera publicació que pretenc completar per unir la meva cartera en un document útil i també sóc artista. Us admetré això, sóc una persona estranya. No sóc perfecte, m'havia acudit amb la llei fins i tot que m'ha portat a deixar els col·legis i a les universitats i deixar els estats per intentar fer -me un nom amb més èxit. Sóc una dona per naixement, porto maquillatge, faig fotos de mi, porto vestits i altres roba de dona, i em quedo conscient de la meva dona per naturalesa. He tingut problemes amb altres persones en el passat que condueixen a lluites per escriure i crear WebApps, i demano disculpes perquè no he pogut posar aquest llibre a les mans abans: ho necessitava. Voldreu llegir i escriure codi que sembli el meu i funciona com el meu i fa el mateix, però encara millor, perquè si us podeu permetre comprar aquest llibre en lloc de combatre el teclat com ho faig només per crear un llibre que demani diners per a això, teniu els recursos que necessiteu per tenir èxit a la vostra vida. Vaig tenir tota mena de problemes amb la família creixent, les condicions de salut, els metges, els mitjans de comunicació i la llei i el meu codi reflecteix profundament la lluita que és el feminisme i la naturalesa femenina en un món dividit i frustrat. Tot i això, aquest llibre és una cosa que m'importa profundament, el meu nadó, la meva cartera i la meva vida, així que agraeixo la vostra consideració quan porteu el text a casa i us porti amb cura per aprendre de mi. Tingueu en compte que no sóc perfecte, aquest llibre tindrà errors, revisions i noves edicions i haureu de pensar amb el vostre cervell lògic el millor que pugueu per tenir una experiència exitosa amb la meva redacció. A més, enteneu que vull dir bé per a vosaltres, fins i tot quan us enfronteu a reptes a l'hora d'escriure. Penseu -hi així: quan només podeu llogar un sistema informàtic per fer qualsevol cosa que pugueu imaginar a l'espai digital, emmagatzemar tota la informació que trobeu, analitzar -la i organitzar -la i arribar a entendre -ho, inevitablement trobareu dificultats amb la informació que esteu ingerint i fins i tot publicant. T'ho dic perquè em trobo amb les mateixes dificultats. Utilitzeu aquest llibre al vostre propi risc, treballa amb la teva comunitat i comunitats a la teva disposició per crear programari en un entorn segur i no prengui les coses personalment quan fallis o fins i tot triomfa de la manera equivocada: així és com he arribat fins ara, i per què puc portar -te aquest text i ajudar -te a tenir èxit sense divergir -te per un camí de bogeria que em deixa arruïnar, esmicolat i engreixat Treballarem, Internet. És possible que no estigueu molt familiaritzats amb qui sóc amb només unes paraules, però us animo a llegir -vos, em coneixereu mentre continueu llegint i entenent -me mentre construïu els vostres propis projectes per completar la vostra obra. No hi haurà deures amb aquest llibre, sempre que els vostres professors o professors no us assignin cap, però us animo molt a crear una cartera de projectes vosaltres mateixos a mesura que llegiu, així com un projecte de pedra de pedra que mostri com podeu aplicar el que heu après. El meu projecte Capstone és la base de la majoria del que llegireu en aquest llibre, ja que incorpora el codi dels meus projectes anteriors, el codi que he creat i après a escriure de manera metòdica a mà i una àmplia gamma d'idees i consells que m'han ajudat a tenir èxit fins al punt on puc girar una aplicació senzilla que es presenta completament i sembla i es comporta com una aplicació popular que podríeu veure al vostre amic o a la família que s'utilitza, a Internet, anunciada, o a la notícia.

Què és aquest llibre: Aquest llibre és un tutorial per exemple. Podeu trobar codi aquí, instruccions sobre com aprendre a codi, informació sobre el codi de depuració i solucionar els errors, resoldre els passos, instruccions sobre com fer una còpia de seguretat i desar el vostre codi, tornar a desplegar si algú trenca el vostre codi, assegurar el vostre codi, desplegar el vostre codi, crear llocs web interactius que siguin entretinguts, involucrats i addictius i obtindreu una idea de qui sóc, per què és important i com es pot retratar la vostra imatge i la imatge, així com la imatge i la companyia, així com la imatge i la companyia, així com la imatge i la companyia, així com la imatge i la companyia, així com la imatge i la companyia, així com la imatge i la companyia, així com la imatge i la companyia, així com la imatge de la vostra empresa, així com la imatge de la vostra empresa, així com la imatge i la companyia, així com la imatge i la companyia, així com la imatge i la companyia, així com la imatge de la vostra empresa, i la imatge de la vostra empresa, i la imatge de la vostra emissió, i la imatge de la vostra empresa. Construeix la millor llum absoluta per ser la més atractiva possible per als teus usuaris finals, els visitants del lloc web. En aquest llibre, demostraré diversos exemples de disseny de programari amb un focus centrat en la web com a plataforma i també la seguretat. Iniciarem l'experiència d'aprenentatge mitjançant la creació d'un projecte bàsic mitjançant l'UNIX Shell, amb funcions de còpia de seguretat i script. A continuació, examinarem un lloc web bàsic del bloc, actualitzarem el nostre bloc amb funcions fotogràfiques i de vídeo, així com utilitzar aquestes funcions per utilitzar solucions de seguretat mitjançant programari lliure i assegurar el nostre servidor mitjançant un mòdul d'autenticació pluggable (PAM). A continuació, revisarem la manipulació i el processament de fitxers, explorant l'edició de vídeo, la donació de veu, la exploració de codis de barres i el reconeixement de caràcters òptics, entre altres conceptes. Al llarg del camí examinarem les API que ens ajudaran a fer que el nostre programari sigui més útil i segur, amb opcions gratuïtes i de pagament. Al llarg del camí, explorarem eines de seguretat física i militants, com ara les armes de foc i el disseny de municions i la fabricació, incloent disseny de canó i repetidor, disseny de torretes i drone, i altres principals que integrarem amb el nostre programari a la xarxa existent per protegir el nostre programari i demostrar l'autodefensa i la resilitud. Farem pauses al llarg del camí per crear jocs, motors de representació 2D i 3D i treballarem amb maquinari incrustat en exemples d'estudi de cas de programari bàsic de representació dimensional i un massatge electrònic vibrant en cautxú de silicona respectivament. Al llarg del camí, també utilitzarem solucions d'aprenentatge automàtic ja disponibles per tal d'assegurar millor el nostre programari. També utilitzarem eines de borsa disponibles per a la web per tal de racionalitzar i assegurar el procés. Aquest llibre és una guia per al vostre èxit en la creació d'una aplicació web i la integració amb una xarxa professional d'ordinador i sistemes mecànics incrustats, i en general una guia per crear programari i maquinari incrustat sense coneixement de fons ni experiència prèvia.

Què no és aquest llibre: Si realment voleu tenir un lloc web, només podríeu configurar una botiga senzilla i vendre el que necessiteu, publicar un bloc, publicar fotos o vídeos, o d'una altra manera sense escriure mai una sola línia de codi. Aquest llibre no és això. Aquest llibre us ensenyarà a crear programari que sigui més útil, completament destacat, funcional i segur que qualsevol programari que ja pugueu trobar, perquè desplega el programari més recent que encara és prototips, pot ser costós de funcionar a una escala més gran que operen i no apel·li a les empreses que no s'ajusten a les empreses que s'estableixen per a les persones que realment no fan res. Si seguiu aquest llibre de prop, voldreu escriure codi, codi de recerca, crear les vostres pròpies aplicacions i guanyareu diners amb el que feu. Guanyaré diners amb aquest llibre, fins i tot en etapes primerenques, perquè conté informació que la gent necessita i vol llegir, i ja compren quan compren o utilitzen les meves aplicacions. Aquest llibre no crearà una aplicació per a vosaltres, però us indicarà en la direcció correcta i us armarà amb les eines que necessiteu i les habilitats i consells que facilitaran el vostre propi èxit en la creació de programari per a la web, amb totes les línies de codi que haureu d'escriure com a exemple, a punt per ser combinats en programari que vosaltres i els vostres seguidors, convidats, clientela, amics, familiars, contractistes i la gent d'Internet vulgui fer servir i assistència.

Què aprendràs: Aquest llibre us ensenyarà a crear i vendre programari, programari realment funcional, útil, enregistrament de suports, funcions de seguretat com el reconeixement facial, l'escaneig de codis de barres de zona llegible per a màquines, les API web per autenticar, enregistrar i presentar vídeo i intercanviar missatges com Bluetooth i COMUNICACIÓ DE CAMP (NFC). Aquest llibre us ensenyarà a utilitzar un ordinador en xarxa, centrant -vos en Debian Linux, com crear codi bash per fer instal·lar i fer una còpia de seguretat del vostre programari una brisa automàtica perfecta, com crear el codi Python com a backend per servir a missatges dinàmics, estil o altres finalitats, exploració d'identificació, moderació d'imatges i vídeo, microtransaccions de dades per mantenir el vostre programari segur, processament de pagaments, negociació de criptomoneda, tasques asíncrones i molt més. Aprendreu a crear els vostres propis dispositius Bluetooth, amb bateries, carregadors, microcontroladors, circuits, motors i sensors, utilitzant soldadura, filferro i impressió 3D, així com materials de fosa. Demostraré els principals de disseny 3D aplicats a la fabricació i la fabricació d'eines i la matriu additius, de manera que podreu fabricar els vostres propis dispositius de maquinari incrustats amb bateries integrades, carregadors, circuits electrònics i sortides funcionals. i en xarxa amb Bluetooth i la web. Concretament, examinarem dos estudis de cas, un massatge vibrador i una arma de foc casolana, tots dos programats a OpenSCAD, que està disponible com a interfície gràfica o utilitat de línia de comandaments i es pot integrar en una web per obtenir resultats més ràpids. Aprendràs a crear i desplegar un lloc web des de la base sense experiència prèvia, fer -lo funcional, segur, bell, útil i el més important. Aprendràs a utilitzar l'aprenentatge de màquines i la visió de l'ordinador per fer un lloc segur i més pràctic, gravar vídeo i àudio des del vostre lloc web, donar la vostra veu, fer música i modular l'àudio per crear mostres útils, i com trencar el soroll aprofitant altres llocs web per crear la millor xarxa possible de llocs web que pugueu enllaçar directament amb els vostres per compartir tota la informació útil que heu d'oferir i encara més important portar persones al vostre programari i al vostre negoci. Aquest llibre se centrarà molt en els mitjans de comunicació, la seguretat i l'aprenentatge de màquines, que són els tres components principals que us ajudaran a crear programari útil per a la web mitjançant la participació dels usuaris adequats i desvinculant els equivocats d'una manera realista, pràctica, dedicada i dedicant -se alhora que també és automàtica i robusta. Aquest llibre ensenya a UNIX, concretament Debian (Ubuntu), Bash Shell, Python, HTML, CSS, JavaScript i diversos paquets de programari útils per a Python com peticions, així com un programari Bash útil com GIT i FFMPEG. També us ensenyaré a comerciar automàticament la criptocurrency i fer pagaments en criptocurrency o des de targetes de dèbit habituals, fins i tot pagar als visitants una part dels vostres ingressos si ho decidiu. Us ensenyaré a guanyar diners del vostre lloc web a través de la publicitat, com preparar la vostra aplicació per als motors de cerca i fer -la ràpida, classificada en el primer rànquing per al que els vostres clients cercaran per trobar -vos i classificar -vos en tantes cerques comunes com sigui possible. Us ensenyaré a vendre el vostre programari, anunciar -lo, apel·lar als clients que busquen els vostres serveis i fer -vos un nom a Internet a través de vies que ja existeixen, són barates i funcionen bé. Us ensenyaré a desar les vostres dades en ordinadors de núvols que us funcionin i guardeu les vostres dades de manera barata, com planificar i crear un lloc web que faci el que els usuaris volen i el que vulgueu i com mantenir els usuaris compromesos posant al vostre lloc un toc als seus telèfons amb notificacions, correu electrònic, missatges de text, trucades telefòniques i més vies per tornar els usuaris al vostre lloc web a la vostra disposició a la vostra disposició del clic del clic d'un botó només de protecció. Aquest llibre se centrarà en la pràctica de publicar i distribuir suports en grans quantitats, des de text fins a fotos fins a vídeos a àudio, fer una bona impressió en els usuaris finals (la vostra clientela) i vendre't de qualsevol manera que ho facis per crear un lloc web, una aplicació que sigui representativa de tu i només, i et fa, el teu programari i la teva empresa semblen bé de la millor manera possible. També aprendràs alguns consells i trucs de mi, des de consells de codificació, vanitat pràctica com el maquillatge i la fotografia, el modelatge i l'actuació, i molt més, cosa que serà important per retratar -se a tu mateix i a la teva empresa amb la millor llum possible amb totes les eines disponibles mentre distribueix el contingut que necessitis en un saludable equilibri de plataformes per portar el teu programari a la fruita amb més esforç, treball o diners que sigui necessari. Aquest llibre es diu "PràcticWeb Based Deep Learning and Security by Example" for a reason: It deals with learning to code, specifically for the web, specifically with a focus on security, from a practical standpoint, with examples of working code that serves the practical purposes outlined in the text. The learning component of this text also encompasses machine learning, the code I will show you how to run for the web that will handle computer vision, facial recognition, image and video moderation, image enhancement, resolution Millora, subtítols d'imatges i altres tasques com les mètriques de predicció procedents d'imatges, com ara la naturalesa de la imatge com a imatge autèntica i transferida per ordinador o una còpia òptica (una foto d'una imatge o una foto impresa) és molt important quan es tracta de seguretat web i de seguretat de programari, perquè pot preformar els tasques que d'altra manera són impossibles. Amb la cara. Ús). Qualsevol que construeixi programari que sigui impecable té una idea del que això implica. El programari és inherentment insegur perquè els dispositius i els comptes que utilitzem per accedir -hi no sempre estan a la nostra disposició, podrien estar en mans de qualsevol persona amb mala intenció del programari i, per tant, poden suposar un risc per al propi programari. Això és el focus d'aquest llibre. De manera predeterminada, un ordinador en xarxa està protegit amb un token de tecla llarg, anomenat i SSH o Secure Shell Key, i d'altra manera es fixa millor amb un servidor web, perquè el servidor web proporciona l'accés obert i les eines de seguretat d'última generació que s'executen al servidor mateix. El servidor web té accés al navegador web de l'usuari, que és probablement la part més potent del dispositiu de l'usuari, perquè és el lloc on l'usuari pot accedir al programari en xarxa. Aquest kit d'eines pot representar el text, les pàgines web que veieu, i també pot gravar imatges, àudio i vídeo (com una foto d'una cara o un identificador d'estat), pot llegir i escriure a dispositius de ràdio Bluetooth i poden llegir i escriure a les etiquetes de transponderació de camp properes, les targetes de clau econòmiques, els fobs, els adhesius, els anells i fins i tot els implants de xip amb números de sèrie únics que es poden llegir i escrits a les dades generades i validades per un servidor web enllaçats al lloc web en el lloc web. Utilitzant totes les eines a la vostra disposició, amb aquest llibre us equipareu amb els coneixements per crear un lloc web segur i, en general

Per on començar: Us convidem a saltar la secció amb la qual comenceu aquest llibre o qualsevol secció, al codi exacte que necessiteu, sobretot si teniu experiència amb la codificació abans o alguna de les eines esmentades, descriuré detalladament en aquest llibre, així com en documentar casos d'ús i exemples pràctics. Si no teniu experiència en el codi d'escriptura, us recomano que llegiu tot aquest llibre i, sobretot, us recomano que llegiu les seccions anteriors, per assegurar -vos que aquest llibre sigui adequat per a vosaltres. Si aquest llibre no és adequat per a vosaltres, considereu -lo regalar a un amic o familiar que pugui estar interessat en aprendre sobre el desenvolupament de la web i, fins i tot, considereu -lo en préstec i aprendre d'ells per omplir els buits on us he fallat com a professor o altres professors que ho feien davant meu. Comenceu on ho fareu, cada part d'aquest llibre serà útil si teniu la intenció de crear una aplicació útil i considereu que les millors aplicacions es creen tenint en compte l'usuari final: Conegueu el vostre client. Ara em coneixeu, ja coneixeu aquest llibre i ja esteu a punt per començar. Per començar, agafeu un ordinador (fins i tot l'ordinador portàtil més barat d'una botiga de caixa, Amazon o un escriptori antic funciona i configureu -lo de manera que us funcioni.

Com llegir aquest llibre: El text ressaltat, denota que el text pertany a un missatge d'ordres, on escriureu el codi que executeu. L'indicador d'ordres està molt enfocat al teclat i requereix poc o no fer clic, accelerant el flux de treball i us facilita les coses.

Començant: Formem -nos. Començarem per crear codi en una màquina local i començarem sense crear un lloc web connectat a Internet. Això és més segur per començar, no costa res i és fàcil per a vosaltres. Depenent del vostre sistema operatiu, entrar en una closca bash serà una mica diferent. Per a Mac OS, us recomano que instal·leu una màquina virtual en aquest moment, ja que obtindreu la major compatibilitat amb una màquina virtual. Diversos proveïdors com VirtualBox i Paralells poden executar una màquina virtual per a vosaltres, tot i que també és possible instal·lar Ubuntu directament a la màquina, si preferiu utilitzar un entorn natiu que es recomana per crear una experiència ràpida i racionalitzada. Si utilitzeu Linux o Windows, que us recomano, hauria de ser molt fàcil crear un projecte. Obriu el terminal, ajusteu el dimensionament tal com considereu adequat i comenceu el pas 2. Si utilitzeu Windows, seguiu el pas 1.

Pas 1: - Només els usuaris de Windows A Windows, obriu el símbol de comandes com a administrador i tipus WSL –install

Pas 2: - Continueu aquí o salteu el pas 1 fins aquí si no utilitzeu Windows En un terminal obert, (segons el vostre sistema operatiu, anomenat Ubuntu a Windows, Terminal a Mac o Linux, o un nom similar), comenceu per crear un projecte. Ho fem amb l'ordre mkdir, que crea un directori. Si necessiteu crear un directori per emmagatzemar el vostre projecte, que es recomana, utilitzeu l'ordre CD per canviar al directori i i i i i i i i i

CD/PATH/TO/DIRECTORY - La ruta són les carpetes (fitxers) que precedeixen el vostre directori de destinació, la vostra ruta predeterminada és ~ o/home/nom d'usuari (on el nom d'usuari és el vostre nom d'usuari). Per canviar al directori per defecte, escriviu CD o CD ~ Exemple Mkdir: substituïu "exemple" pel nom del directori

Ara teniu un directori de treball per al vostre projecte. Com que és tan important tenir aquest directori desat en cas que necessiteu canviar a una màquina diferent o desplegar el codi que escriviu, de manera que estigui a punt per a la web, crearem un script per fer una còpia de seguretat del vostre directori en els propers passos. Però crear un script requereix una mica de codi i cal automatitzar el codi per ser el més útil possible. Per tant, creem un guió per crear scripts primer. Comencem creant el script i fent -lo executable. Utilitzarem sudo, chmod i toqueu per això i anomenarem el script "Ascript".

Sudo Touch/USR/Bin/Ascript sudo chmod a+x/usr/bin/ascript sudo nano/usr/bin/ascript

Ara hem creat el script, el va fer executable i estem preparats per editar -lo. Nano és un editor de text que us permetrà editar text sense fer clic, cosa que és molt més fàcil que utilitzar una interfície gràfica d'usuari. Per editar un fitxer amb Nano, utilitzeu Nano i després la ruta al fitxer. Per fer un guió que faci un guió, és bastant similar a fer el nostre guió en primer lloc. Utilitzarem el mateix codi que anteriorment, substituint el nom de l'script, "Ascript" per un paràmetre d'argument, 1 $. Això ens permet trucar al guió escrivint simplement Sudo Ascript Newscript, moment en què podem crear qualsevol guió nou substituint "Newscript" pel nom del vostre script. El codi de Nano hauria de semblar:

Sudo Touch/USR/Bin/$ 1 sudo chmod a+x/usr/bin/$ 1 sudo nano/usr/bin/$ 1

I per tancar Nano, podem mantenir la tecla de control i prémer x, i després per denotar que estem desant el fitxer i fer clic a la devolució. Ara, en lloc d'escriure aquestes tres ordres per editar un script, podrem escriure Sudo Ascript Ascript per editar de nou l'script. Això funciona! I qualsevol nou script es pot executar fàcilment trucant -lo a la closca. Desa el nostre treball ara: escrivim un script de còpia de seguretat per desar el nostre nou guió i, a continuació, recolzeu -lo al nostre directori de projectes, alhora que feu una còpia de seguretat del script de còpia de seguretat.

Còpia de seguretat de Sudo Ascript

Ara, a Nano:

sudo cp/usr/bin/backup/path/to/directori/ sudo cp/usr/bin/ascript/path/to/directori/

On/ruta/to/directori és el camí cap al projecte que heu creat amb MKDIR. Més endavant, aprendrem a copiar rutes de repetició com aquesta amb un bucle i una llista, que és menys codi, però de moment mantenim -la senzilla i tinguem algunes línies. Per executar aquest script i feu una còpia de seguretat del vostre codi, deseu el fitxer a nano amb control+x, y i return i escriviu el següent al vostre shell

còpia de seguretat

Si se us demana una contrasenya mentre llegiu aquest llibre i seguiu al llarg del shell, introduïu correctament la contrasenya de l'usuari, tindreu tres intents abans de tornar a executar l'ordre. Podeu utilitzar les fletxes amunt i avall per tornar a engegar les ordres i editar -les, si necessiteu executar qualsevol cosa dues vegades. Premeu simple amunt i avall de manera intermitent per seleccionar una ordre, abans d'editar l'ordre amb les fletxes dretes, esquerre i suprimir la tecla, així com el teclat i executar -la amb retorn.

Felicitats! Heu aconseguit crear un guió de còpia de seguretat impressionant que faci una còpia de seguretat de dos scripts importants de Shell al vostre directori de treball. Podríem moure les coses més endavant a mesura que el projecte es fa més gran, però això funciona de moment. Passem a fer una còpia de seguretat al núvol, utilitzarem GitHub per a això (tot i que hi ha moltes altres solucions Git per a la còpia de seguretat, són iguals.) Git és un programari de control de Verision que us permet fer una còpia de seguretat de les edicions al vostre programari a mesura que les feu a un servidor, alhora que us permet descarregar sencers de còpies del vostre programari darrere d'una contrasenya o clau. És fonamental per desar el vostre programari, sobretot quan migrem a les instàncies de Linux assegurades que de vegades es trenquen quan una sola línia de codi falla, deixant -vos bloquejat mentre no es pot fer una còpia de seguretat si no teniu la possibilitat de fer -ne una còpia de seguretat automàtica, que cobrirem.

Si encara no utilitzeu una màquina virtual Ubuntu en aquest moment, us recomano que utilitzeu una màquina virtual Ubuntu en aquest moment perquè us facilitarà la vida quan instal·leu tots els paquets necessaris per crear un lloc web de treball i preformar operacions d'aprenentatge profund al vostre ordinador. Passarem el codi a un servidor web en un futur proper, però volem assegurar -nos que hi hagi almenys algunes capes de seguretat darrere del nostre servidor web resistents al phishing i que utilitzin diversos paquets Linux per fer -ho. Si encara voleu utilitzar Mac OS, us convidem a cercar i instal·lar els paquets necessaris en línia, però és possible que no hi hagi alternatives per a cada paquet que aquest llibre o sèries cobrirà.

Afegim unes quantes ordres per comprometre el nostre treball amb l'script de còpia de seguretat executant la còpia de seguretat de la comanda sudo Ascript.

# ... git afegit –tot git commit -m "còpia de seguretat" Git push -u Origin Master

...

Una vegada més, controleu X per estalviar.
sudo touch /usr/bin/ascript
sudo chmod a+x /usr/bin/ascript
sudo nano /usr/bin/ascript
Ara hem de fer una configuració de temps per a aquest projecte. Com que aviat serà un projecte Git, no cal que escrigui totes les ordres cada vegada que ens despleguem des d'un dipòsit de Git, però obtindrem el penjat quan escrivim els nostres scripts de desplegament. Per començar, assegurem -nos que estem al directori adequat i inicialitzem el dipòsit de Git i generem tecles SSH.

CD/Path/to/Directori git init Git Branch -M Mestre ssh-keygen

Després d'escriure SSH-KeyGen, la nova clau s'hauria d'estalviar a la carpeta domèstica sota una carpeta anomenada .SSH. Es diu id_rsa.pub. Trobem aquesta clau i la copiem. Per veure -ho,
sudo touch /usr/bin/$1
sudo chmod a+x /usr/bin/$1
sudo nano /usr/bin/$1
CD ~ Cat .SSH/ID_RSA.PUB

Copieu el text que es retorna per la darrera ordre i creeu un compte amb el vostre proveïdor Git (idealment GitHub), abans d'afegir la clau SSH al vostre compte. Un cop tingueu un compte, feu clic al menú superior dret i introduïu la configuració, abans d'afegir la tecla SSH a les tecles SSH i GPG a l'accés al menú. Seleccioneu Afegiu una tecla SSH i afegiu -la enganxant -la i donant -li un títol abans de desar i tornar a GitHub per crear un nou dipòsit. Això és similar per a altres proveïdors de Git, haureu de llegir la seva documentació. A la nova configuració del dipòsit, doneu al vostre dipòsit un nom descriptiu i decidiu si voleu publicar -lo i assegureu -vos de configurar encara no hi ha fitxers per a la seva inclusió. Un cop creat el dipòsit, copieu el clon amb URL SSH i enganxeu -lo a la següent comanda.

git remot Afegeix git: // ... (el vostre URL remot)
sudo ascript backup
Ara podeu tornar al vostre dipòsit amb CD, coneixereu això. Proveu el vostre script de còpia de seguretat ara amb còpia de seguretat

Genial! Ara podem obtenir codificació. Instal·lem Django ara que tenim una bona comprensió a Bash i Git. Django ens permetrà fer una còpia de seguretat automàtica del nostre programari, Bash també ho pot fer, però Django hauria de tenir una implementació més segura més senzilla (es pot desactivar i configurar amb més facilitat).

Per instal·lar programari a Ubuntu, utilitzarem la comanda Sudo Apt-Get. Primer, actualitzem i actualitzem el programari que ja teníem. Això es pot fer amb l'actualització de Sudo Apt-Get i l'actualització de Sudo Apt-Get. A continuació, instal·lem Python i el nostre entorn virtual, la llar del nostre codi, amb la següent comanda: sudo apt-get instal·leu python-is-python3 python3-venv
sudo cp /usr/bin/backup /path/to/directory/
sudo cp /usr/bin/ascript /path/to/directory/
Això és tot el que necessiteu per anar amb Django en termes d'instal·lacions de programari a la instància d'Ubuntu. Per a Windows i Linux, això hauria de ser bastant senzill, però per a Mac potser voldreu instal·lar una màquina virtual i Linux mitjançant un entorn virtual gratuït o de pagament com VirtualBox o Paralells Desktop i recrear els passos anteriors per tal de configurar un entorn Ubuntu. Ubuntu és fonamental en aquest cas perquè és el programari que els llocs web s'executen i els permet allotjar llocs web amb tot el programari esmentat.

Cavem al Django.

Al nostre directori de nou, amb CD:
backup
python -m venv venv # crea l'entorn virtual on s'emmagatzema el codi font venv/bin/activar # activa l'entorn virtual PIP instal·la el django django-admin startproject mysite. # On MySite és el projecte que estic començant al meu directori actual.

Crea l'entorn virtual on s'emmagatzema el codi

Activa l'entorn virtual

On Mysite és el projecte, començo al meu directori actual.

Django acaba de començar, perquè Django allotja el servidor web i està fent tot el que necessitem per aconseguir que un lloc web local bàsic funcioni. Ara que tenim instal·lat Django, editem una mica la configuració perquè funcioni com necessitem. Primer, creem una nova aplicació

Python Manage.py startapp Feed

Notareu que la primera aplicació es diu Feed. L'aplicació s'hauria d'anomenar qualsevol cosa que vulgueu i crearem noves aplicacions, però el nom de cada aplicació ha de ser coherent cada vegada que es fa referència a l'aplicació al codi. Per afegir una aplicació nova, sempre editarem la configuració.py a l'altre directori l'aplicació creada, anomenada a StartProject, App HereFher. Utilitzant nano,

Nano App/Settings.py

A la configuració, cerqueu Installed_Apps i separeu el [] en 3 línies. Utilitzant quatre espais a la línia central buida, afegiu -hi "pinso" o el nom de la vostra aplicació. Aquesta secció de la configuració.py ha de semblar:
# Instal·lat_apps = [
    'alimentar',
]
Abans d'oblidar -nos, posem a prova que Django funciona. Utilitzant la comanda Python Manage.py runserver 0.0.0.0.0:8000, podem executar el servidor i, a continuació, navegar en un navegador web a l'ordinador que executa el codi a http: // localhost: 8000 i veure un exemple de pàgina web (funciona!) Deixar el servidor amb control C, el mateix que qualsevol altre ordre.

Ara, cavem a escriure algun codi Python. Django té tres components principals, tots ells executats per codi completament. Els components s'anomenen model, vista i plantilla, i cadascun és a un nivell més alt i inferior respectivament abans que la pàgina web es lliuri a l'usuari.

El model és el codi que emmagatzema informació a la base de dades per a la recuperació, la classificació i la representació.

La vista decideix com es rendeix, manipula i modifica el model, gairebé totes les visualitzacions utilitzaran un model directament.

La plantilla és el codi HTML amb algunes campanes i xiulets addicionals anomenats llenguatge de plantilla. La plantilla es presenta per la vista on s'omple de codi i context Python com ara models i informació (Strings i nombres enters) des de la vista.
cd /path/to/directory
git init
git branch -m master
ssh-keygen
Django també té altres components, inclosos, però sense limitar -se a:

Configuració, que configura l'aplicació tal com vam parlar.

URL, que són patrons que l'usuari segueix per accedir a parts específiques de l'aplicació web.
cd ~
cat .ssh/id_rsa.pub
Els formularis, que defineixen com es gestiona la informació que s'envia al servidor i es lliura tant a la base de dades com a l'usuari. Aquests són el fonament de la informació de processament del costat del servidor i pot acceptar qualsevol tipus d'informació que els magatzems de l'ordinador, sobretot les cadenes de text, els números i els veritables/falsos booleans (normalment caselles de selecció).

Les plantilles, que són el codi HTML i el llenguatge de plantilles i el pont de la bretxa entre Python i HTML, és a dir, la informació de Python es pot servir com a codi HTML al qual qualsevol pot accedir i pot assegurar un lloc web amb accés restringit, alhora que fa que el codi Python sigui accessible a la web i sigui útil per a una varietat de propòsits en un dispositiu remot que no necessiti estar a prop del servidor.

Els fitxers estàtics, que solen ser JavaScript i són les biblioteques que serveix el servidor i estan vinculats amb la plantilla.
git remote add git://… (your remote URL)
Els fitxers de suports, que el servidor serveix o estan allotjats externament, o simplement escrits al servidor abans de processar -los i publicar -lo a un altre servidor (un cub) per allotjar -se.

Middleware, que és un codi que s'executa al mateix temps que cada vista i es considera "inclosos" a la vista.

Processadors de context, que processen el context de cada vista i s'utilitzen per afegir context addicional.

Les proves, que validen que l'usuari o la sol·licitud passa determinats requisits abans que es mostri la vista.

Els consumidors, que dicten com manegen i responen a la comunicació.

Administrador, que s'utilitza per registrar models perquè es puguin manipular detalladament a la pàgina d'administració de Django, on es pot administrar la base de dades mitjançant una interfície gràfica.

L'api, que defineix les tasques asíncrones parts del codi Django poden començar a funcionar abans de continuar immediatament a la següent tasca o línia de codi.

Django pot tenir molts altres components, que parlarem amb detall aquí. Hi ha moltes maneres de fer que Django sigui més funcional, afegint bocines, que són canals de comunicació ràpids i racionalitzats, api, que executa tasques asíncrones i multitud d'altres programes per ampliar Django, especialment en les funcions de vista, on s'executa la major part del codi. Les funcions de vista són claus perquè solen declarar cada codi específic per a un patró d'URL específic o una secció del servidor.

Primer, explorem les funcions de vista. Les funcions de vista comencen amb les importacions que denoten codi que s'utilitzaran a la vista i es defineixen mitjançant definicions o classes de funció regular. Les vistes més simples es defineixen per la definició de la funció Def i retornen una httPresponse amb una plantilla bàsica. Comencem per definir una vista bàsica per retornar el text "Hello World". Recordeu que cada vegada que afegiu codi després d'una declaració com Def, si, mentre, per a, etc., haureu d'afegir 4 espais per a cadascuna de les definicions anteriors que voldríeu aplicar a la vostra funció. Ens endinsarem en el que significa cadascun d'aquests aviat.

Des del directori del nostre lloc, editeu el fitxer Feed/Views.py mitjançant Nano i afegiu les línies següents al final del fitxer.

de django.http import httPresponse def hello (sol·licitud): retorn httpresponse ("hola món")

HttPresponse de Django respon amb una cadena de text, denotada amb l'obertura i el tancament '. Cada vegada que passeu informació a una funció o classe, com ara la sol·licitud o una cadena, haureu d'utilitzar parèntesis (, obertura i tancament).

Això no és tot el que necessitem per veure la nostra visió encara. Per descomptat, no hem explicat al servidor on és la vista exactament, encara hem de definir un camí per la qual es pot presentar la vista. Comencem per definir una ruta bàsica en aplicacions/urls.py, i entrarem en grups de ruta més endavant.
python -m venv venv # A app/urls.py, afegiu una línia després de les declaracions d'importació després d'importar la vista que acabem de crear.
source venv/bin/activate # des de les visualitzacions d'importació de pinsos com a Feed_Views
django-admin startproject mysite . # Ara, definim el patró de vista. Els patrons de vista tenen tres components, el component de ruta, que indica al servidor on existeix la vista dins del servidor (la ruta de l'URL que l'usuari escriu a la barra de navegació per entrar a la pàgina web), el component de vista on s'especifica la vista i un nom amable per a la vista, de manera que és fàcil recuperar el patró quan es treballa amb una plantilla, especialment perquè el nom es pugui canviar i actualitzar si cal fer un altre punt de vista o prendre un nom més lògic. Té sentit fer les coses d'aquesta manera i ser flexible, perquè la vostra base de codis serà un entorn canviant que necessiti flexibilitat i improvisació per ser valuós i fàcil de treballar. A continuació, es mostra com serà la vostra visió, podeu afegir -ho a l'UrlPatterns = [Secció d'App/URLS.Py. El patró de vista es defineix amb els tres components descrits anteriorment i una funció anomenada ruta. Els vostres patrons d'URL són una llista, així que assegureu -vos d'acabar sempre cada element amb una coma, perquè això separa cadascun. Cada element també ha d'anar en una línia nova, una vegada més amb quatre espais abans, de la mateixa manera que l'aplicació a Settings.py. Definirem el primer component de la vista amb una funció de cadena buida, per tal de crear una vista que s'executa al directori arrel del servidor web. Els vostres URLS.Py ara haurien de semblar així:
des de les visualitzacions d'importació de pinsos com a Feed_Views urlPatterns = [ ruta ('', Feed_views.hello, name = 'hola'), ]

Aquesta és la base per crear un lloc web amb Django completament estàtic. Per tal de fer un lloc web més dinàmic on puguem començar la informació sobre caché, com imatges, vídeos, àudio i molt més, haurem d'utilitzar models, que explorarem a continuació. Per ara, comprovem el nostre codi i executem el servidor. Per comprovar els errors del codi, executeu:

Python Manage.py Check
python manage.py startapp feed
Si hi ha missatges d'error, haureu de revisar detingudament els canvis que heu fet a l'aplicació i veure si hi ha alguna cosa que cal arreglar, com un espai estrany o mancat, un caràcter addicional, una cadena no inclosa, qualsevol tipus de lletra, qualsevol personatge suprimit o qualsevol altra cosa. Llegint el missatge d'error (si en teniu), haureu de poder veure la ruta a un fitxer que heu creat o editat juntament amb un número de línia, així que mireu aquest fitxer i línia i veure si podeu solucionar qualsevol cosa que hi hagi. Si heu solucionat el problema, torneu a executar la comanda anterior. Quan el vostre programari estigui a punt per executar -lo i funcioni, veureu que la sortida "Comproveu el sistema identificat sense problemes". Ara ja estàs a punt per anar -hi. Executeu el servidor amb:

Python Manage.py Runserver 0.0.0.0.0:8000

Ara obriu un navegador web i aneu a http: // localhost: 8000. Heu de veure el text retornat al parèntesi i les cites de la funció httPresponse a la vostra vista. Aquest és només un exemple bàsic, però si ho heu arribat fins aquí, enteneu els fonaments bàsics de com funcionen Linux, Bash, Python i Django. Anem a aprofundir en algun modelatge de bases de dades i explorem la potència d'una classe Python en l'emmagatzematge d'informació. Aleshores, començarem a agafar una adherència a HTML i CSS abans de fer que el nostre lloc sigui completament destacat, flexible i segur mitjançant l'aprenentatge de JavaScript i Machine.
nano app/settings.py
Les classes s'emmagatzemen als models.py de la vostra aplicació. Utilitzant Nano, edita aplicacions/models.py i afegeix una nova classe. Una classe es defineix amb la definició de la classe i es passa una superclasse de la qual hereta, en aquest cas models.model. El nom de la classe es produeix després de la definició de la classe i, després de la definició de classe A: (Colon), abans que es denotin els atributs i les definicions de funció lligades a la classe. La nostra classe necessita un identificador que podem utilitzar per recuperar -lo i mantenir -lo únic, i també necessita un camp de text per emmagatzemar informació. Més endavant podem afegir una marca de temps, fitxers, booleans (definicions veritables o falses que poden ajudar el nostre codi a prendre decisions sobre què fer amb el model i es pot utilitzar per ordenar -lo), una instància per lligar el model a un usuari iniciat en sessió al servidor i molt més. Desempaquetem el codi següent:

de django.db Models d'importació # La importació que s'utilitza per definir la nostra classe i és atribut Classe Post (models.model): # La definició de la nostra classe id = models.autofield (primària_key = true) # L'identificador del nostre model, una tecla generada automàticament que ens permetrà consultar el model, mantenir -lo únic i és útil quan hem d'interactuar amb el model un cop creat. Text = models.TextField (default = '') # L'atribut de les nostres classes de classes, en aquest cas, algun text, per defecte a una cadena buida.

La importació que s'utilitza per definir la nostra classe i és atribut
INSTALLED_APPS = [
    'feed',
]
La definició de la nostra classe mateixa

L'identificador del nostre model, una clau generada automàticament que ens permetrà consultar el model, mantenir -lo únic i és útil quan hem d'interactuar amb el model un cop creat.

Atribueix les botigues de la nostra classe, en aquest cas, algun text, que es produeix per defecte a una cadena buida.

Tanqueu i deseu el fitxer com ho vam fer abans per acabar.

Hi ha molts altres camps i opcions que explorarem quan actualitzem aquesta classe a mesura que evolucioni la nostra aplicació, però aquesta és les necessitats bàsiques de crear una aplicació per publicar algun text. Tot i això, aquest model no funcionarà sol. Tal com s'ha descrit abans, necessitarem una vista personalitzada i un patró d'URL personalitzat per fer que aquest model funcioni, i també necessitarem un formulari juntament amb una plantilla. Explorem primer el formulari.

Per definir un formulari, editeu App/forms.py amb nano i afegiu les línies següents. Necessitarem dues importacions, la nostra classe de formularis, així com el model que hem creat (Feed.Models.Post), una definició de classe similar al model i un camp juntament amb una subclasse anomenada meta que definirà el model amb el que interacciona el formulari. El formulari també pot tenir una funció d'inicialització que la configuri en funció de la informació de la sol·licitud, model o d'una altra manera, ho explorarem més endavant.

Els formularis de model són tan útils perquè poden crear un model o també editar un model, de manera que els utilitzarem per a tots dos. Definim -ne un en forma. Py a continuació.

de formes d'importació de django de Feed.models Import Post Classe postform (formes.modelform): text = forms.charfield (widget = forms.textArea) Classe Meta: Model = Post Fields = ("text",)

Aquest és el bàsic del que sembla una forma i model. Aquest formulari de model es pot utilitzar per instanciar o editar una publicació, canviant el text que conté. Veurem integrar aquest formulari en una vista a continuació. Primer, fem les migracions i migrem la base de dades perquè el nostre codi pugui interactuar amb el model quan s'executa. Per fer -ho, executeu les ordres següents:

Python Manage.py Makemigrations Python Manage.py Migrate

Això trigarà un minut a executar -se, però un cop ho faci, us permetrà accedir al model a les vistes, middleware o en qualsevol altre lloc del programari. Continuem fent una vista on podem veure el nostre model. Edita Feed/Views.py i afegeix el codi següent, com s'ha apuntat. No haureu d'afegir res després del signe #, aquest codi és comentaris que s'utilitzen per denominar informació sobre el codi. Començarem per importar el nostre model a les visualitzacions i afegir -lo a un context on puguem representar -lo en una plantilla com a llista de visualització. A continuació, afegirem una plantilla on puguem representar el formulari i el model amb un botó per crear un objecte nou basat en el model i publicar -la al servidor. Això sembla complicat, així que anem a pas. Abans d'acabar la vista, creem una plantilla que acaba de fer el model i ens assegurem que puguem veure -la creant una publicació nova a la closca. A continuació, es mostra com hauria de semblar aquesta vista:

de Feed.models Import Post de django.shortcuts import render, redirect de django.urls importen revers Def Feed (sol·licitud): Publicacions = Post.Objects.All () # Consulteu totes les publicacions de la base de dades fins ara return render (sol·licitud, "Feed/Feed.html", { "Publicacions": publicacions, })

Consulteu totes les publicacions de la base de dades fins ara

Tot sembla bastant senzill fins que arribem a la part inferior. Render, el valor retornat per la funció en lloc de en una resposta HTTP com l'exemple anterior, sempre pren una sol·licitud com a primera entrada, accepta un context (en aquest cas les publicacions de la base de dades), que ara es poden representar a la plantilla i retorna la plantilla definida a la funció. La plantilla serà un document HTML amb una mica d'un llenguatge anomenat jinja2, que converteix la informació de Python a l'HTML.

Per començar a crear plantilles, feu dos directoris a Feed.

plantilles mkdir/plantilles plantilles/plantilles mkdir/pinso

A continuació, editeu una plantilla al directori anterior, alimenta/plantilles/alimentació i afegiu el codi per a aquest exemple. Vegem la plantilla per a aquest exemple.

Menjar { % per a publicacions en publicacions %} {{post.text}} { % EndFor %}

Aquesta és una plantilla molt senzilla. Defineix l'obertura i el tancament d'etiquetes HTML, una etiqueta de tipus de document, una etiqueta de cos amb un títol de llegenda, una etiqueta de ruptura que afegeix una petita línia a la pantalla i un bucle per a que fa cada publicació a la llista de publicacions com a paràgraf de la plantilla. Això és tot el que es necessita per presentar publicacions, però encara no n'hi ha cap a la base de dades. Creem -ne alguns amb la closca. Podem executar el shell amb gestiona.py

Python Manage.py Shell

Ara, importem el nostre model de publicació

de Feed.models Import Post

A continuació, crearem una publicació senzilla amb una cadena i sortirem de la closca. La cadena pot ser qualsevol cosa, sempre que sigui un text vàlid.

Post.objects.create (text = 'hola món') sortida ()

Finalment, haurem d'afegir un patró d'URL al nostre feed. Com que la nostra aplicació de feed utilitzarà diversos URL i volem mantenir les mides de fitxers petites, creem un URL local.

de django.urls ruta d'importació de. Importa vistes urlPatterns = [ ruta ('', views.feed, name = 'feed'), ]

També haurem d'editar l'URL.Py a l'aplicació Base, qualsevol cosa que decidim anomenar -la, aquest va ser el primer directori que vam crear. Edita App/App.py i afegeix el següent als patrons de l'URL

des de django.urls import inclou # a la part superior urlPatterns = [ #... codi anterior aquí ruta ('feed/', include ('Feed.urls'), nomspace = 'feed')), ]

A la part superior

... Codi anterior aquí

Ara, quan executem el servidor amb Python Manage.py Runserver, veurem la pàgina que hem creat perquè tenim el model, la vista i la plantilla, així com el patró d'URL, juntament amb els elements de la base de dades. A continuació, implementem el formulari que hem creat i comencem a crear les nostres pròpies publicacions. Però abans d'escriure massa codi, anem a fer una còpia de seguretat mitjançant el guió que vam escriure anteriorment, còpia de seguretat. Executeu aquest guió al shell, espereu uns moments i tot el codi es recolzarà al nostre dipòsit de Git.

còpia de seguretat

La implementació del formulari és relativament senzill. Importarem el nostre formulari, afegirem un gestor de sol·licituds de publicació a la vista i guardarem la publicació a la base de dades abans de redirigir -se a la mateixa vista. Podem utilitzar la funció de redirecció que ja hem importat i una altra funció anomenada inversa per obtenir l'URL per al patró de vista. Ho consultarem amb la cadena "Feed: Feed" perquè l'espai de nom del patró inclòs és l'alimentació i la vista també s'anomena pinso.

de Feed.Forms Importa postForm Def Feed (sol·licitud): Publicacions = Post.Objects.All () # Consulteu totes les publicacions de la base de dades fins ara si request.Method == 'Post': # Gestionar la sol·licitud de publicació format = postForm (request.post) # Creeu una instància del formulari i deseu -ne les dades si form.is_valid (): # valideu el formulari form.save () # Desa el nou objecte RETORNAR REDIRECT (inversa ("Feed: Feed")) # redirigiu -vos a la mateixa URL amb una sol·licitud d'obtenció return render (sol·licitud, "Feed/Feed.html", { "Forma": postForm (), # Assegureu -vos de passar el formulari al context perquè puguem representar -la. "Publicacions": publicacions, })

Consulteu totes les publicacions de la base de dades fins ara

Maneu la sol·licitud de la publicació

Creeu una instància del formulari i deseu -ne les dades

Validar el formulari

Deseu el nou objecte

Redirigiu -vos a la mateixa URL amb una sol·licitud d'obtenció

Assegureu -vos de passar la forma al context perquè puguem representar -la.

Etiqueta a html i representant el formulari a la plantilla HTML amb un botó d'enviament. També necessitarem un token CSRF, un testimoni que impedeixi que els llocs externs es publiquin al formulari sense carregar una pàgina.

Menjar { % csrf_token %} {{forma}} Nou post { % per a publicacions en publicacions %} {{post.text}} { % EndFor %}
from django.http import HttpResponse

def hello(request):
    return HttpResponse('hello world')
Anem a desglossar això. Hi ha una nova classe de formulari, un testimoni, el formulari en si i un botó d'enviament. Bastant senzill, però quan ho fem una ullada, potser voldríem que es vegi millor. Funciona, podem publicar publicacions noves amb el formulari i ara es guarden a la base de dades. Hi ha algunes coses aquí. Utilitzem les etiquetes HTML per declarar que el document és un document HTML, utilitzem una etiqueta de plantilla ({ % ... %}) per fer el token per al formulari i un altre, {{...}} per representar el formulari. També tenim un bucle per representar el text mitjançant etiquetes de bloc i una etiqueta de plantilla. Les etiquetes de blocs són realment importants perquè podem definir com es mostren les seccions de la plantilla i les etiquetes de plantilla són la base de com introduïm variables al nostre codi.

Ara hem de fer que la nostra aplicació es vegi millor, perquè de moment sembla realment bàsica. Podem fer -ho mitjançant CSS, ja sigui en línia o en classes lligades a cada objecte del document. CSS és molt agradable perquè explica tot el que ha de semblar i pot fer que sembli molt bo. Hi ha algunes biblioteques que poden fer -ho, però el meu personal és Bootstrap.

getbootstrap.com/

Feu un nou directori anomenat plantilles amb plantilles mkdir i, a continuació, editeu plantilles/base.html.

Hauria de semblar així:

{ % Block Body %} { % EndBlock %}

Assegureu -vos de copiar els fitxers CSS i JavaScript, els fitxers .CSS i .JS, perquè necessitarem el JavaScript per fer el nostre lloc més funcional en el futur.
from feed import views as feed_views
Ara, tornem al Bash Shell i executem una ordre ràpida. Recordeu -vos que si alguna vegada heu d'accedir a l'entorn virtual, escriviu Venv/bin/activeu. Això us permetrà instal·lar paquets Python localment de manera que permeti a Django accedir -hi. Per donar les nostres formes generades per les classes de Bootstrap Django, utilitzarem un paquet Python anomenat formes cruixents. Podem descarregar -ho amb la següent comanda

PIP Instal·leu formes django-crispy

Un cop instal·lat això, afegiu -lo a la configuració.py
from feed import views as feed_views

urlpatterns = [
    path('', feed_views.hello, name='hello'),
]
Instal·lat_apps = [ # ... codi anterior aquí "Crispy_forms", ]

... Codi anterior aquí

Ara, de nou a la nostra plantilla de pinsos, podem eliminar algunes coses. Eliminem l'inici i el final del document i el substituïm per herència de la nostra plantilla de base, utilitzant extensions i la definició del bloc. A més, afegirem una importació de filtre de plantilla amb càrrega i un filtre de plantilla al formulari. Finalment, afegim una classe de bootstrap al botó del formulari per fer que sembli més un botó. Això hauria de semblar així:
python manage.py check
{ % s'estén 'base.html' %} { % Block Body %} { % de càrrega crispy_forms_tags %} { % csrf_token %} {{forma | crispy}} Nou post { % per a publicacions en publicacions %} {{post.text}} { % EndFor %} { % EndBlock %}

Bonic! Ja és una mica de codi. A continuació, hauríem de provar -ho i assegurar -nos que podem veure que tot sembla agradable i, a més, assegureu -vos que tot funciona correctament. Executeu el servidor segons les instruccions anteriors i assegureu -vos que el lloc es veu i funciona bé. Gran feina! Esteu preparats per passar al següent pas, en el qual afegirem una funcionalitat d'inici de sessió d'usuari mitjançant URL, formularis, vistes i plantilles similars. La plantilla de base és important i continuarem modificant -la i fent canvis segons sigui necessari, però de moment ens centrem en fer més segura el nostre lloc, permetent als usuaris iniciar la sessió amb un nom d'usuari i una contrasenya i, eventualment, una informació encara més important que ajudarà a mantenir la vostra aplicació segura i el vostre propi compte només accessible per vosaltres.

Per fer -ho, haurem d'utilitzar el model d'usuari integrat a Django. El model d'usuari és un model de base de dades, com la nostra publicació, que es pot presentar per registrar un usuari al lloc web. En el futur, abans de desplegar el lloc a Internet, ampliarem aquest model amb altres models atribuïts a ell i crearem mesures de seguretat addicionals per a l'inici de sessió resistents a la pesca. Començarem per utilitzar alguns formularis d'inici de sessió integrats que proporciona Django. Primer, creem una nova aplicació que utilitzarem per presentar les plantilles i les visualitzacions de la pàgina d'inici de sessió bàsica. També crearem altres aplicacions per representar els reptes d'inici de sessió continuats per tal d'assegurar l'aplicació, inclosos un Pincode, el reconeixement facial, la comunicació de camp proper, els dispositius externs, l'autenticació multi factor i el reconeixement d'empremtes dactilars.
python manage.py runserver 0.0.0.0:8000
Ja hem parlat de començar una aplicació. Des del nostre directori, dins de l'entorn virtual, Pass Manage.py Aquests arguments

Python Manage.py StartApp Usuaris

Ara, hauríem de tenir un directori per a la nova aplicació. Comencem creant una vista en aquest directori que correspon a l'inici de sessió de l'usuari. Django ha creat les visualitzacions per als inicis de sessió d'usuaris, però aquests no seran adequats per a nosaltres perquè necessitem una vista personalitzada, que es fa preferentment amb una definició.

En aquesta visió, començarem comprovant una sol·licitud de publicació, passeu request.post a un formulari d'inici de sessió importat de django, autentiqueu el compte d'usuari i inicieu la sessió a l'usuari abans de redirigir -los a la nostra aplicació de feeds.

A usuaris/visualitzacions.py, afegiu el codi següent
from django.db import models # de django.shortcuts import render, redirect
de django.urls importen revers
de django.contrib.auth.forms import autenticationForm, setPasswordform
de django.contrib.auth import autenticate, inici de sessió
de django.contrib.auth import inici de sessió com a auth_login
de django.contrib Missatges d'importació

DEF Inici de sessió (sol·licitud):
    si request.method == "POST":
        nom d'usuari = request.post ['nom d'usuari'] # Obteniu el nom d'usuari i la contrasenya de la sol·licitud de publicació
        contrasenya = request.post ['contrasenya'] # autenticar l'usuari
        user = autenticate (nom d'usuari = nom d'usuari, contrasenya = contrasenya)
        Si usuari:
            auth_login (sol·licitud, usuari, backend = 'django.contrib.auth.backends.modelbackend')
            missatges.success (sol·licitud, "la vostra contrasenya s'ha acceptat. Continua")
            RETURNA REDIRECT (inversa ("Feed: Feed")))
        else: missatges.warning (sol·licitud, "nom d'usuari o contrasenya incorrecte. Torneu -ho a provar")
    return Render (sol·licitud, "usuaris/login.html", {'form': autenticationForm ()})
class Post(models.Model): # Obteniu el nom d'usuari i la contrasenya de la sol·licitud de publicació
    id = models.AutoField(primary_key=True) # Autentica l'usuari
    text = models.TextField(default='') # Això és tot el que necessiteu per a una vista bàsica d'inici de sessió. Ara, creem un formulari per a la vista ampliant la plantilla base. Començarem creant un nou directori per a plantilles a la carpeta dels usuaris.
Usuaris/plantilles de mkdir Usuaris/plantilles de mkdir

Ara, hauríem de poder editar usuaris/plantilles/usuaris/login.html. Mentre hi estem, crearem una plantilla per permetre que l'usuari també s'inscrigui.

usuaris nano/plantilles/usuaris/login.html

Ara, a la plantilla,

{ % s'estén 'base.html' %} { % de càrrega crispy_forms_tags %} { % Block Content %} { % csrf_token %} Iniciar sessió {{forma | crispy}} Iniciar sessió { % EndBlock %}

Aquest és el bàsic d'una plantilla d'inici de sessió. És realment com l'altra plantilla d'estructura, però sembla una mica diferent quan es representa. Podem copiar aquest codi per crear una altra plantilla molt similar anomenada Registre.html, on canviarem la redacció i utilitzarem un nou formulari que construïm. Fem la plantilla primer. Edita usuaris/plantilles/usuaris/registreu.html i afegiu el codi següent:

{ % s'estén 'base.html' %} { % de càrrega crispy_forms_tags %} { % Block Content %} { % csrf_token %} Creeu un compte {{forma | crispy}} Registrar { % EndBlock %}

Ara, creem un formulari per al nostre registre d'usuaris i tornem a fer la volta a les visualitzacions abans d'actualitzar els nostres inicis de sessió d'usuari amb un model. Farem aquest formulari bàsic per començar, però incorporareu més detalls i funcions de seguretat com ara acords i captcha en el futur. Editeu els formularis amb usuaris/formes nano i afegiu el codi següent.

de formes d'importació de django de django.contrib.auth.models importeu usuari des de django.contrib.auth.forms import usuelCreationForm Classe userRegisterForm (userCreationForm): correu electrònic = format.meilfield () Classe Meta: Model = Usuari fields = ['nom d'usuari', 'correu electrònic', 'contrasenya1', 'contrasenya2']
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',)
Així doncs, tenim una altra forma aquí, que funciona bastant simplement. És un formulari de registre d'usuari amb un nom d'usuari, correu electrònic i contrasenya, així com un camp de contrasenya de confirmació. Tingueu en compte que aquest formulari no amplia les formes regulars. Un camp es defineix igual i el meta de classe defineix el model que el formulari correspon a la resta de la informació que s'escriurà al formulari. La major part d'això ja existeix a la creació d'usuari integrada de Django, de manera que ho farem servir com a base per a la classe (passada al parèntesi).

A continuació, examinarem la vista per registrar un usuari, ara que tenim un formulari i una plantilla. Es tracta d'una forma model, igual que la de la nova vista de la publicació. Edita els usuaris/views.py i afegeix el codi següent:

# ... importacions des de .Forms import userRegisterform DEF Registre (Sol·licitud): si request.method == "POST": format = userRegisterForm (request.post) si form.is_valid (): user = form.save () missatges.success (sol·licitud, "Benvingut a l'aplicació, {}.". Format (user.username)) Return Render (sol·licitud, "Usuaris/Registre.html", {'Form': userRegisterform})
python manage.py makemigrations
python manage.py migrate
... Importacions

Això és tot el que necessitem per registrar un usuari, però hauríem de tenir més informació. Volem conèixer el temps que l'usuari es va registrar, a quina hora van ser per última vegada al lloc, alguna informació sobre ells, com una biografia, un horari horari, etc. A més, haurem d'actualitzar el nostre model de feed, publicar, per tenir en compte el model d'usuari i atribuir publicacions a cada usuari. Per fer -ho, actualitzarem els models.py a les dues aplicacions. Comencem per editar el model de pinsos. Hauria de semblar així:

Des de Django.db Models d'importació # ... Importacions de django.contrib.auth.models importeu usuari Publicació de classe (models.model): id = models.autofield (primària_key = true) autor = models.foreignKey (usuari, on_delete = models.cascade, null = true, en blanc = true, relacionat_name = 'publicacions') # Afegeix en aquesta línia text = models.TextField (default = '')
    posts = Post.objects.all() # ... Importacions
Afegiu en aquesta línia

Fixeu -vos en la segona línia que es va afegir al fitxer. Aquesta és una clau estrangera, que atribuirà cada publicació a un sol usuari per publicació, de manera que podem assegurar-nos que desarem les publicacions de forma d'usuari i no es pot fer cap publicació sense atribuir-la a un usuari. Definim aquesta clau estrangera amb la classe que representa, un argument d'eliminació per assegurar -se que les publicacions s'eliminen amb els usuaris, els arguments nuls i en blanc per assegurar -nos que podem eliminar l'usuari si cal i per adaptar -nos a la manca d'un usuari en publicacions que ja hem creat i un nom relacionat que podem utilitzar per referir -nos als objectes de publicació que crea l'usuari. Aquest nom relacionat, a diferència de Post.Author, l'autor de la publicació, ens proporciona als usuaris que han publicat la publicació en si. Ara podem obtenir les publicacions que un usuari realitzi executant user.posts.all () o autor.posts.all ().

Ara, fem que els nostres inicis de sessió siguin més resistents. Ja podem fer que el nostre lloc sigui molt menys vulnerable al phishing, simplement limitant el nombre de vegades que permetrem un inici de sessió al lloc, això és força fàcil. Comencem també a emmagatzemar informació sobre cada usuari abans que continuem desenvolupant la nostra aplicació. Edició d'usuaris/models.py, afegiu el codi següent.

de Models d'importació de django.db de django.contrib.auth.models importeu usuari de django.utils Importa el temps de temps Perfil de classe (models.model): user = models.onetoOneField (usuari, on_delete = models.cascade, null = true, en blanc = true, relacionat_name = 'perfil') comptabilitat last_seen = models.DateTimeField (default = TimeZone.now) can_login = models.DateTimeField (default = TimeZone.now) preferit_name = models.charfield (max_length = 20, default = '', null = true, en blanc = true) bio = models.textField (en blanc = true, default = '')

Tingueu en compte que aquest model és bastant similar al model de publicació. Tenim una importació addicional, Timezone, que ens permetrà definir els valors predeterminats als camps de DateTime, i també tenim un personatge i un camp de text com la publicació. Utilitzar tots aquests segments de temps ens ajuda a assegurar el lloc i a comprendre el seu ús, i els camps de text ens permeten obtenir informació sobre cada usuari o autor, al lloc web. L'OnetooneField hauria de ser l'única consideració menor, es comporta exactament el mateix que un Foreginkey, però amb només un model posterior. D'aquesta manera, l'usuari només té un perfil, mentre que poden tenir moltes publicacions.
mkdir feed/templates
mkdir feed/templates/feed
Ara, millorem la nostra sessió d'inici de sessió i registrem les visualitzacions per tenir en compte el perfil. Primer, editeu usuaris/visualitzacions.py i centreu -vos en la vista del registre:

# ... importacions des de .Forms import userRegisterform DEF Registre (Sol·licitud): si request.method == "POST": format = userRegisterForm (request.post) si form.is_valid (): user = form.save () Perfil.objects.create (user = user) # Assegureu -vos d'afegir aquesta línia per crear un perfil per a l'usuari missatges.success (sol·licitud, "Benvingut a l'aplicació, {}.". Format (user.username)) Return Render (sol·licitud, "Usuaris/Registre.html", {'Form': userRegisterform})

... Importacions
Assegureu -vos d'afegir aquesta línia per crear un perfil per a l'usuari

Això simplement crea un perfil per a l'usuari, sense omplir cap informació. Ara, volem assegurar -nos que el compte d'usuari no es pot iniciar massa sovint, o almenys les contrasenyes no es poden provar massa sovint, així que actualitzem la vista d'inici de sessió.

# ... importacions des de .Models Importa perfil de django.utils Importa el temps de temps Importa dateTime DEF Inici de sessió (sol·licitud): si request.method == "POST": nom d'usuari = request.post ['nom d'usuari'] contrasenya = request.post ['contrasenya'] user = autenticate (nom d'usuari = nom d'usuari, contrasenya = contrasenya) Si user i user i user.profile.can_login <Timezone.now (): # Tingueu en compte que ara comprovem si l'usuari pot iniciar la sessió auth_login (sol·licitud, usuari, backend = 'django.contrib.auth.backends.modelbackend') missatges.success (sol·licitud, "la vostra contrasenya s'ha acceptat. Continua.") RETURNA REDIRECT (inversa ("Feed: Feed"))) Altrament: # Si l'inici de sessió no va tenir èxit, missatges.warning (sol·licitud, "nom d'usuari o contrasenya incorrecte. Torneu -ho a provar.") user = user.objects.filter (nom d'usuari = nom d'usuari) .first () # Aquesta és la part on actualitzem el perfil dels usuaris Si usuari: perfil = user.profile perfile.can_login = timezone.now () + datetime.timedelta (segons = 15) # de manera que no poden tornar a iniciar la sessió durant uns segons perfil.save () return Render (sol·licitud, "usuaris/login.html", {'form': autenticationForm ()})
python manage.py shell
... Importacions

Tingueu en compte que ara comprovem si l'usuari pot iniciar la sessió

Si l'inici de sessió no va tenir èxit,
from feed.models import Post
Aquesta és la part en què actualitzem el perfil dels usuaris

Així que no poden tornar a iniciar la sessió durant uns segons

Aquest és el bàsic fonamental de la seguretat. Assegureu -vos que el lloc no sigui vulnerable a algú simplement provant totes les combinacions de contrasenya possibles, o fins i tot algunes d'elles alhora. Això no serà frustrant per a l'usuari ordinari que conegui la seva contrasenya i només inicia la sessió en uns quants dispositius, però mantindrà nombrosos robots de phishing fora de l'aplicació. Tingueu en compte que hem afegit una instrucció IF amb una variable, can_login, que hauria de ser un moment en el passat i actualitzar -la amb cada inici de sessió sense èxit mitjançant el mateix nom d'usuari. D'aquesta manera, un usuari malintencionat no podrà endevinar una contrasenya enlloc tan ràpidament. El nombre de segons a DateTime.Timedelta () també es pot actualitzar i el lloc web serà més resistent però lleugerament menys utilitzable amb més de segons. Recomano 15 per començar.
Post.objects.create(text='hello world')
exit()
Recordeu -vos que hem creat un guió de còpia de seguretat per salvar el nostre treball, així que anem endavant i donem una còpia de seguretat del que tenim fins ara per assegurar -nos que ho hem guardat tot. Executeu l'ordre:

Còpia de seguretat del sudo

Una vegada més, això estalviarà el vostre treball fins ara. Recomano executar còpies de seguretat freqüents per desar el vostre treball i fins i tot potser voldreu executar un treball de còpia de seguretat automàticament. Podeu fer -ho mitjançant una utilitat UNIX anomenada Cron. Per activar aquesta utilitat, executeu la següent comanda i introduïu la vostra contrasenya:
from django.urls import path
from . import views

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

Si encara no heu seleccionat l'opció 1 per a Nano, l'editor de text que ja heu de familiaritzar i desplaceu -vos a la part inferior del fitxer mitjançant les tecles de fletxa. Afegiu la línia següent:

0 * * * * Còpia de seguretat de Sudo
from django.urls import include # Cron utilitza el format Minut, hora, dia del mes, mes, dia de la setmana, on un * o un número representa quan s'executa l'ordre. Utilitzant un 0 per al minut i * per a la resta d'opcions, podem executar una ordre el primer minut de cada hora al començament del minut. Això ens permet fer una còpia de seguretat del codi automàticament. Totes les feines de Cron quan s'executen amb sudo funcionen com a arrel, de manera que no haurem d'escriure una contrasenya cada hora.
    # Per facilitar la còpia de seguretat del nostre codi sense utilitzar una contrasenya, desactivem la contrasenya per a la nostra comanda de còpia de seguretat. Ho farem executant la següent comanda i introduint una contrasenya:
Sudo Visudo

Ara, desplacem -nos a la part inferior del fitxer i afegim una altra línia:

Tot plegat = NOPASSWD: /bin /Backup
backup
Això ens permet executar la comanda "Còpia de seguretat" com a usuari, sense contrasenya. El format per a això és fàcil, només cal que prefixi la línia amb "All = NoPasswd:/bin/" i finalitzeu amb l'ordre, per exemple/bin/còpia de seguretat, que existeix a/usr/bin/.

Ara, comencem a treballar amb el correu electrònic. El correu electrònic és realment important per als llocs web, perquè és una manera de mantenir un lloc web més segur, verifiqueu que els usuaris són persones reals i, fins i tot, productes o serveis de mercat per als clients. Moltes persones que freqüenten Internet comproven el seu correu electrònic diàriament i reben tota mena de correu electrònic de màrqueting sobre productes i serveis que els interessa. Hi ha algunes opcions a l'hora d'activar el correu electrònic en un lloc web de Django i sereu benvinguts a triar el millor per a vosaltres.

Primer, podeu pagar un servei de correu electrònic que us permetrà enviar correu electrònic des del vostre domini i requereix un codi mínim. Hi ha molts serveis que ofereixen això, com Google Workspace, Sendinblue, Mailgun i molt més.
    posts = Post.objects.all() # En cas contrari, esteu bé de crear el vostre propi servei de correu electrònic al vostre servidor des de zero. Recomano aquesta opció, tot i que és més codi i pot requerir allotjament especial. No podreu iniciar molt probablement un servidor de correu des de l'ordinador de casa, així que anem endavant i examinem la configuració i el codi per enviar correu electrònic abans d'iniciar un servidor al núvol i crear el nostre propi servidor de correu dins.
    if request.method == 'POST': # Primer, editeu la configuració.py amb la següent comanda:
        form = PostForm(request.POST) # Nano App/Settings.py
        if form.is_valid(): # On l'aplicació és el nom de l'aplicació que heu creat amb StartApp.
            form.save() # Afegiu les línies següents:
        return redirect(reverse('feed:feed')) # Site_name = 'Django App'

Correu electrònic_backend = 'django.core.mail.backends.smtp.emailbackend'
Correu electrònic_host = 'localhost'
Correu electrònic_port = 587
Correu electrònic_use_tls = true
Correu electrònic_address = username@server.com '
Correu electrònic_host_user = 'nom d'usuari'
Correu electrònic_host_password = config ['correu electrònic_host_password']
Default_from_email = '{} <{}>'. Format (nom_nom, correu electrònic_host_user)
        'form': PostForm(), # Assegureu -vos de canviar -les quan estigueu preparats per desplegar la vostra aplicació, ho revisarem més endavant. La configuració de correu electrònic_address hauria de ser el correu electrònic del qual voldríeu enviar i la contrasenya (correu electrònic_host_password) s'ha de configurar a la contrasenya que genereu per al servidor. Carregueu la contrasenya des d'un fitxer de configuració per mantenir -la fora del codi mitjançant la lògica següent, per sobre d'aquestes línies a Configuració.py:
Importa el sistema operatiu Importa json amb Open ('/etc/config.json') com a config_file: config = json.load (config_file)

Aleshores, he configurat un fitxer JSON amb la configuració a /etc/config.json mitjançant Nano de la manera següent.

Per editar el fitxer:

sudo nano /etc/config.json
Afegiu les línies següents:

{ "Correu electrònic_host_password": "" }

Continuarem edificant el fitxer de configuració i afegint totes les contrasenyes i tecles que utilitzarem a l'aplicació. Per ara, examinem ràpidament com enviar correu electrònic mitjançant Python. Primer, creem una plantilla per a un correu electrònic de verificació que podem enviar als nostres usuaris i posar -la al directori de plantilles d'usuari. Aquesta plantilla s'escriurà a HTML.

usuaris nano/plantilles/usuaris/verificació_email.html

Aplicació Django: verifiqueu el vostre correu electrònic Estimat {{user.userName}}, Per verificar el vostre correu electrònic, feu clic aquí. De forma alternativa, podeu enganxar el següent enllaç a la barra d'adreces del vostre navegador: {{base_url}} { % url 'usuaris: activar' uidb64 = uid token = token %} L'enllaç caducarà en 30 minuts. Si no heu sol·licitat cap correu electrònic de verificació, només podeu ignorar aquest correu electrònic. Ens veiem allà, Margar

Aquest correu electrònic és bastant senzill. Es necessita un context d'un usuari, l'URL base del lloc i un identificador d'usuari i token que s'utilitzen per verificar el correu electrònic de l'usuari. Assegureu -vos de definir l'URL base a Configuració.py abans d'escriure algun codi Python per representar la plantilla. Seguiu endavant i afegiu les línies següents a App/Configuració.Py, a prop del principi.Site_name = 'Django App' Protocol = 'https' Domini = 'exemple.com' Base_url = protocol + ': //' + dominiFinalment, quan el vostre lloc estigui preparat per a Internet i el desplegueu, voldreu definir el vostre domini com el nom de domini que compreu per representar el lloc. Aquest és el nom que escriureu a la barra de navegació per accedir al vostre lloc. Per ara, podeu deixar el domini en blanc o utilitzar un marcador de lloc. També voldreu canviar el nom de lloc a un nom que vulgueu donar al vostre lloc, que trieu.

Abans d'enviar correu electrònic, creem un generador de token perquè puguem tenir un testimoni d'activació del compte que mai caduca. Podem fer -ho mitjançant la creació i la importació d'un token d'activació del compte que s'assembli a les següents. Edita el fitxer:

usuaris nano/tokens.py

Afegiu el codi següent:

Des de django.contrib.auth.tokens importeu contrasenyaResettokengenerator importar sis Class TokenGenerator (PasswordResettokenGenerator): def _make_hash_value (jo, usuari, marca de temps): tornar ( sis.text_type (user.pk) + six.text_type (marca de temps) Que) comptabilitat_activació_token = tokengenerator () ull

Aquest generador bàsic de token genera un testimoni que podem enviar l'usuari en un URL i l'usuari pot utilitzar per verificar el seu correu electrònic i activar el seu compte.
A continuació, vegem com enviar un correu electrònic. Utilitzant nano, editeu usuaris/correu electrònic.py.

Nano usuaris/correu electrònic.py

Enviar el correu electrònic de verificació HTML semblarà així:

de django.contrib.auth import get_user_model de django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode de django.contrib.sites.shortcuts import get_current_site de django.core.mail import send_mail de django.template.loader import rend_to_string de django.utils.encoding import Force_bytes de django.core.mail import correu electrònic de correu electrònicMultialternatives de django.shortcuts importen render de .Tokens Importa compte_Activation_Token de django.template.loader import rend_to_string de django.utils.html import strip_tags de la plantilla d'importació de django.template, context des de la configuració de la importació de django.conf Importa el traçat DEF SENT_VERIFICACIÓ_EMAIL (usuari): User = get_user_model () mail_subject = '[{}] activeu el vostre compte.'. Format (Settingse.site_name) html_message = Render_to_string ('usuaris/verificació_email.html', { "Usuari": usuari, "Domini": Settings.Domain, "Protocol": "https", 'UID': urlsafe_base64_encode (force_bytes (user.pk)), "Token": compte_activation_token.make_token (usuari), }) send_html_email (usuari, mail_subject, html_message)

Això és bastant senzill. Importem les funcions que necessitem per enviar el correu electrònic, representar el correu electrònic amb plantilles i la nostra configuració, i després definim el correu electrònic pel nom de la plantilla i l'envia a l'usuari mitjançant una funció. Notareu que no hem definit la funció per enviar el correu, SENT_HTML_EMAIL, així que escrivim això a sota del codi que ja hem afegit als usuaris/correu electrònic.py
pip install django-crispy-forms
def Send_html_email (usuari, mail_subject, html_message): TO_EMAIL = user.eMail nom d'usuari = User.userName si to_email == '': No retorneu cap UNSUB_LINK = Settings.base_url + user.profile.create_unsubscribe_link () html_message = html_message + "derrocament" msg = correu electrònicmulcialternatives (mail_subject, strip_tags (html_message), settings.default_from_email, [to_email], capçaleres = {'list-connsubscribe': '<' + ÚNC_LINK + '>'},) msg.attach_alternative (html_message, "text/html") perfil = user.profile provar: msg.send (falla_silenly = fals) Si no, perfil.email_valid: perfil.meil_valid = cert perfil.save () excepte: perfil.meil_valid = fals perfil.save ()

Això és una mica més complex i encara no estem preparats per executar tot aquest codi. Observeu que estem definint un UNCUB_LINK, l'enllaç que l'usuari pot utilitzar per donar -se de baixa dels nostres correus electrònics. Això és important, perquè els usuaris hauran de ser capaços de desactivar els nostres correus electrònics a menys que vulguin veure -los, en qualsevol moment. També afegim una alternativa de text al nostre missatge, que és el missatge HTML despullat de les etiquetes HTML. Per últim, comprovem si el correu electrònic enviat i si no ho fa, marquem al perfil de l'usuari que el seu correu electrònic no és vàlid.

Tornem als models d'usuari perquè puguem fer que tot funcioni. Hem de definir una funció per generar un enllaç per donar -se de baixa i definir un camp booleà per marcar que el correu electrònic de l'usuari no és vàlid.
    # Primer, afegiu les importacions següents a la part superior dels usuaris/models.py
usuaris/models nano.py

# ... de django.core.Signing import Timestamsigner, badsignature, signatureExpirat de django.urls importen revers

...
A continuació, afegim funcions al model d'usuari per fer el token i comproveu el token que s'utilitza per activar el correu electrònic, així com el camp per desar si l'usuari rep amb èxit el seu correu. A usuaris/models.py de nou, afegiu el codi següent al final del model (codi indentat)

# ... correu electrònic_valid = models.booleanField (predeterminat = true) def make_token (jo): retorn TimestaMpsigner (). Signe (self.user.username) def leck_token (jo, token): provar: Key = '%s:%s'%(self.user.username, token) TimestamStaMpsigner (). UNSIGN (clau, max_age = 60 * 60 * 24 * 30) # Vàlid durant 30 dies excepte (badsignature, signatureExpirat): tornar fals tornar cert Def create_unsubscribe_link (self): nom d'usuari, token = self.make_token (). dividit (":", 1) tornar revers ("usuaris: donar -se de baixa", kwargs = {'nom d'usuari': nom d'usuari, 'token': token,})

...

Vàlid durant 30 dies

Això és bastant senzill, utilitzem un TimestamStamSigner, que és una eina bàsica de criptografia, per crear un token que caducarà al cap d'un cert temps, i també utilitzem una altra funció per comprovar si és vàlida. Utilitzem aquestes fitxes dues vegades, una vegada per verificar el correu electrònic i una vegada per obtenir un enllaç de baixa de subscripció.

Ara que en tenim, l'últim de la feina que haurem de fer és a les opinions. Dins d'usuaris/views.py, afegim visualitzacions per verificar l'adreça de correu electrònic i per donar -se de baixa.

usuaris/visualitzacions nano.py
python manage.py startapp users
Primer, afegiu les importacions següents. Vaig llançar -ne uns quants més, així que no haurem de tornar a importar més articles més tard.

de django.contrib.auth import inici de sessió de django.shortcuts import render, redirect, get_object_or_404 de django.contrib.auth.models importeu usuari de django.utils.encoding import Force_str de django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode Importa json Importa sol·licituds Importa DateTime, Traceback de django.contrib Missatges d'importació des de .Models Importa perfil de django.utils Importa el temps de temps de django.views.decorators.cache import Never_cache Des de .Mail Importa Send_verification_Email # Assegureu -vos d'importar la funció d'enviament de correu electrònic de verificació de django.contrib.auth.decorators importen login_required de django.contrib.auth.mixins importen loginrequiredmixin, userPassestestMixin de django.utils.decorators import mètode_decorator de django.http import httpponseredirect des de la configuració de la importació de django.conf de django.utils Importa el temps de temps Importa dateTime importar pytz de django.views.decorators.csrf import csrf_exempt de django.http import httPresponse de django.contrib.auth.tokens import predeterminat_token_generator de django.utils.http import urlsafe_base64_decode de .Tokens Importa compte_Activation_Token

Assegureu -vos d'importar la funció d'enviament de correu electrònic de verificació

És possible que ja tingueu algunes d'aquestes importacions, però no us fa mal repetir -les. Haureu d'importar la funció d'enviament de correu electrònic de verificació, així com comptabilitat_activació_token des d'usuaris.tokens, entre altres importacions.

Ara, a la part inferior del fitxer, afegiu el codi següent:

DEF DESAURSCRIBE (sol·licitud, nom d'usuari, token): user = get_object_or_404 (usuari, nom d'usuari = nom d'usuari) if ((request.user.is_authenticated i request.user == user) o user.profile.check_token (token)): # Descriviu -los perfil = user.profile perfil.subscribed = false perfil.save () Return Render (sol·licitud, "usuaris/no subscripte.html") # En cas contrari, redirigeix ​​a la pàgina d'inici de sessió Missatges.Warning (sol·licitud, el vostre enllaç de baixa de subscripció ha caducat. Inicieu la sessió a la baixa de subscripció. ') next_url = revers ('usuaris: descriure', kwargs = {'nom d'usuari': nom d'usuari, 'token': token,}) retorn httPresponseredirect ('%s? Next =%s'%(inversa ('inici de sessió'), Next_url)) def activar (sol·licitud, uidb64, token): provar: uid = force_str (urlsafe_base64_decode (uidb64)) user = user.objects.get (pk = uid) excepte (typeerror, valueError, overflowerror, user.doesnotexist): Usuari = Cap ip = get_client_ip (sol·licitud) Si l'usuari no és cap i el compte_activation_token.check_token (usuari, token): user.profile.email_verified = true user.profile.save () user.save () # SendWelCenteMail (sol·licitud, usuari) Misstes.Success (sol·licitud, F'Thanks per confirmar el vostre correu electrònic! Ara podeu iniciar la sessió al vostre compte i us ha enviat un correu electrònic de benvinguda. ') return redirect (user.profile.create_face_url ()) els altres: missatges.success (sol·licitud, el vostre enllaç d'activació ha caducat. Sol·liciteu un nou enllaç d'activació. ') return redirect ("verificar: verificar") DEF RESEND_activació (sol·licitud): si request.method == 'post': format = reenSpendPativationEmailForm (request.post) correu electrònic = request.post ['correu electrònic'] provar: user = user.objects.get (correu electrònic = correu electrònic) send_verification_email (usuari) missatges.success (sol·licitud, "el vostre correu electrònic de verificació enviat. Feu clic a l'enllaç del vostre correu electrònic per verificar el vostre compte.") return redirect (inversa ("verificar: verificar")))) excepte: missatges.warning (sol·licitud, el vostre correu electrònic no és correcte. Torneu -ho a provar. ') els altres: Form = ResendactivationEmailForm () Retorn Render (sol·licitud, "usuaris/reen restauració

Descriviu -los
        username = request.POST['username'] # En cas contrari, redirigiu -vos a la pàgina d'inici de sessió
        password = request.POST['password'] # SendWelCenteMail (sol·licitud, usuari)
Aquest és molt de codi. Anem a desglossar -ho. La primera funció, neta i senzilla, descriu l'usuari de la llista de correu. La segona funció activa el seu correu electrònic i notareu que he afegit una funció comentada, SendWelendeMail. Us convidem a utilitzar una plantilla de correu electrònic i una definició de funció per enviar un correu electrònic de benvinguda, encara no ho he fet. La darrera funció que vaig llançar és important, perquè els correus electrònics d'activació caduquen. Per tant, haurem de tornar a enviar el correu electrònic d'activació alguna cosa del temps. Podem utilitzar un formulari bàsic per a això i trucar a la funció per enviar el correu electrònic de verificació. Abans de fer -ho, assegurem -nos que s'envia en primer lloc, afegint una trucada de funció a la vista del registre. Afegiu aquesta línia just abans de la redirecció a la vista del registre, el registre def, als usuaris/views.py.

usuaris/visualitzacions nano.py

# ... (després) Def Register (Sol·licitud): send_verification_email (usuari) # ... (abans) redirigeix ​​(
mkdir users/templates
mkdir users/templates/users
... (després) Def Register (Sol·licitud):

... (abans) redirigeix ​​(

No heu d'afegir les primeres i últimes línies d'aquest fragment de codi, només assegureu -vos que la vista del registre envia el correu electrònic de verificació a l'usuari. Hauria de semblar així:
nano users/templates/users/login.html
# ... importacions des de .Forms import userRegisterform DEF Registre (Sol·licitud): si request.method == "POST": format = userRegisterForm (request.post) si form.is_valid (): user = form.save () send_verification_email (usuari) # Assegureu -vos d'afegir aquesta línia. missatges.success (sol·licitud, "Benvingut a l'aplicació, {}.". Format (user.username)) Return Render (sol·licitud, "Usuaris/Registre.html", {'Form': userRegisterform})

... Importacions

Assegureu -vos d'afegir aquesta línia!
Ara, haurem d'afegir un formulari per reenviar el correu electrònic d'activació. A usuaris/formes.py, afegiu el formulari següent:

# ... (importacions) Class ResendactivationEmailForm (Forms.Form): Correu electrònic = formes.EmailField (obligatori = True)

... (Importacions)
També necessitarem una plantilla corresponent a aquest formulari d'activació de correu electrònic de reenició. Afegim aquesta plantilla a. Edita el fitxer:

usuaris nano/plantilles/usuaris/reen restauració_activació.html

A continuació, afegiu el codi següent al fitxer.
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']
{ % s'estén 'base.html' %} { % Block Content %} { % de càrrega crispy_forms_tags %} { % csrf_token %} Reenenqueu el correu electrònic d'activació {{forma | crispy}} Reenenqueu el correu electrònic d'activació { % EndBlock %}

Whew, això és molt! Ara, quan despleguem el codi al nostre servidor, podrem enviar correu electrònic HTML i activar els comptes d'usuari amb un clic al correu electrònic. També potser voldrem enviar un simple correu electrònic de benvinguda, així que anem a veure com fer -ho. Torneu a usuaris/correu electrònic.py, afegiu el codi següent:

DEF SendWelCenteMail (usuari): User = get_user_model () html = obert ('{}/usuaris/benvinguda subjecte = 'benvingut a' + settings.site_name + ', {{nom d'usuari}}!' plantilla = plantilla (html) subjtemplate = plantilla (subjecte) context = context = {{'nom d'usuari': user.userName, 'base_url': settings.base_url, 'model_name': 'Daisy holton,' site_name ': Settingse.site_name}) RenderedTemplate = template.render (context) subjContext = context ({'nom d'usuari': user.userName}) subjrenderedTemplate = subjtemplate.render (subjContext) send_html_email (usuari, subjrenderedTemplate, RenderedTemplate)

A més, necessitarem una plantilla per oferir tota aquesta informació. Al meu lloc web, la plantilla sembla la següent, però us convidem a formatar -la.

Benvingut a {{site_name}} Hola {{nom d'usuari}}, Estem encantats de veure't aquí! Gràcies per unir -vos a {{site_name}} i formar part de la diversió. Per començar, aquí teniu algunes coses que podeu fer després de verificar la vostra identitat. Utilitzeu l'aplicació. Aquesta és la pàgina principal de {{site_name}} Visiteu el meu perfil privat {{site_name}}. Aquesta és una pàgina per a qualsevol persona que vulgui conèixer -me. Més perfils. Podeu trobar aquestes persones al lloc i veure el seu contingut. Consulteu totes les publicacions aquí. Aquesta és la pàgina principal privada de {{site_name}}. Hi ha encara més al lloc, així que no dubteu a visitar i veure què trobeu. Podeu compartir el lloc amb qualsevol dels botons socials de cada pàgina. Espero que gaudiu del vostre temps amb {{site_name}}! Gràcies per estar aquí. Amb molt d'amor, {{model_name}} {{base_url}}
# Tingueu en compte que no tenim etiquetes de tancament del cos ni de HTML, perquè les afegim quan afegim l'enllaç HTML de baixa de subscripció. Aquests són importants, però no volem definir -los dues vegades.
Llavors, què hi ha a continuació? Hem recorregut un llarg camí. Realment, hauríem d'estar preparats per desplegar el lloc a un servidor. Podem afegir el decorador @Login_Required i fer que les nostres visualitzacions siguin segures, fer inscripcions d'usuaris, enviar un correu electrònic compatible i informació de memòria cau, que és la base del que ha de fer un lloc web per mantenir -se rellevant. Afegirem algunes funcions més útils i, a continuació, crearem una base per desplegar el nostre codi a un servidor remot, configurar un servidor de correu, configuració de domini i filtres per fer el nostre lloc segur i adequat.

També necessitarem una vista de restabliment de contrasenya, per tant, afegim -ho realment ràpid. La vista de restabliment de contrasenya de Django es trenca en algunes funcions, però veurem com escriure la nostra pròpia vista, la plantilla de correu electrònic, els formularis i els patrons d'URL. Això és el que sembla la vista, a usuaris/visualitzacions.py

#... importacions de django.contrib.auth.tokens import predeterminat_token_generator de django.contrib.auth.forms import SetPasswordForm de django.utils.http import urlsafe_base64_decode DEF PASSWORD_RESET (sol·licitud, uidb64, token): user = get_object_or_404 (usuari, id = urlsafe_base64_decode (uidb64)) si request.method == 'post': form = setPasswordForm (usuari, request.post) si form.is_valid () i default_token_generator.check_token (usuari, token): form.save () missatges.success (sol·licitud, "la vostra contrasenya s'ha restablert.") elif no form.is_valid (): missatges.warning (sol·licitud, "Les vostres contrasenyes no coincideixen o no compleixen els requisits. Torneu -ho a provar.") devolució de redirecció (request.path) els altres: missatges.warning (sol·licitud, "l'enllaç de restabliment de la contrasenya ha caducat. Creeu -ne un de nou.") return redirect (inversa ("usuaris: inici de sessió"))) Retorn Render (sol·licitud, 'usuaris/contrasenya_reset_confirm.html', { "Títol": "Restableix la teva contrasenya", 'Forma': SetPasswordForm (usuari)
from django.db import models # ... Importacions
    author = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True, related_name='posts') # Aquest formulari està integrat a django, però necessitarem una plantilla per confirmar el restabliment de la contrasenya, usuaris/plantilles/usuaris/contrasenya_reset_confirm.html
{ % s'estén 'base.html' %} { % de càrrega crispy_forms_tags %} { % Block Content %} { % csrf_token %} Restableix la contrasenya {{forma | crispy}} Restableix la contrasenya { % EndBlock Content %}

També tenim una plantilla per enviar un correu electrònic de restabliment de contrasenya, amb un formulari senzill, en usuaris/plantilles/usuaris/contrasenya_reset.html

{ % s'estén 'base.html' %} { % de càrrega crispy_forms_tags %} { % Block Content %} { % csrf_token %} Restableix la contrasenya {{forma | crispy}} Sol·liciteu el restabliment de la contrasenya { % EndBlock Content %}

La plantilla del correu electrònic en si és senzilla, és un fitxer HTML bàsic que presenta un enllaç per restablir la contrasenya, a usuaris/plantilles/usuaris/contrasenya_reset_email.html. Django interpretarà automàticament aquest fitxer.

Uglek: restabliu la vostra contrasenya Hola, Per restablir la vostra contrasenya, feu clic aquí. Alternativament, podeu enganxar el següent enllaç al navegador: https://uglek.com { % url 'password_reset_confirm' uidb64 = uid token = token %} Si no heu sol·licitat un restabliment de contrasenya, simplement podeu ignorar aquest correu electrònic. Gràcies per unir -nos a nosaltres, Margar
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='')
També necessitarem dues plantilles més. El primer és confirmar que s'ha enviat el correu electrònic. Les visualitzacions per a aquestes ja es troben a Django, per la qual cosa només hem d'adreçar -les a les URLs.py. Aquesta plantilla es troba a usuaris/plantilles/usuaris/contrasenya_reset_done.html

{ % s'estén 'base.html' %} { % Block Content %} S'ha enviat un correu electrònic amb instruccions per restablir la vostra contrasenya. { % EndBlock Content %}

I, per últim, per confirmar que el restabliment de la contrasenya està completat, usuaris/plantilles/usuaris/contrasenya_reset_complete.html

{ % s'estén 'base.html' %} { % Block Content %} S'ha definit la vostra contrasenya. Inicieu la sessió aquí { % EndBlock Content %}

Ara, necessitem patrons d'URL per a aquestes vistes. A usuaris/urls.py, afegiu els patrons d'URL següents:
# urlPatterns = [
    #... URL anteriors aquí
    ruta ("contrasenya-reset/",
         auth_views.passwordresetView.as_view (
             template_name = 'usuaris/contrasenya_reset.html',
             html_email_template_name = 'usuaris/contrasenya_reset_html_email.html'
         ),
         nom = 'contrasenya_reset'),
    ruta ("Reset de contrasenya/feta/",
         auth_views.passwordresetdoneview.as_view (
             template_name = 'usuaris/contrasenya_reset_done.html'
         ),
         nom = 'contrasenya_reset_done'),
    ruta ("contrasenya-reset-confirm ///",
         Auth_Views.PasswordResetConfirmView.as_view (
             Template_name = 'usuaris/contrasenya_reset_confirm.html'
         ),
         name = 'password_reset_confirm'),
    ruta ("contrasenya-reset-complet/",
         auth_views.passwordresetcompleteView.as_view (
             template_name = 'usuaris/contrasenya_reset_complete.html'
         ),
         nom = 'contrasenya_reset_complete'),
]
            Profile.objects.create(user=user) # ... URL anteriors aquí
Quatre plantilles, això és molt! Però ara podem estar segurs de restablir la contrasenya de l'usuari en qualsevol moment que necessitem, tot des del navegador web.

Entenc que això és molt de codi. Si sembla una mica sobre el cap, està bé. Millorareu, la vostra comprensió millorarà i sereu molt més competents amb el codi molt aviat. Si esteu totalment perduts, us recomano que torneu a aquest programari després de treballar en un curs d'aprenentatge autònom en línia. Normalment són gratuïts per començar i us guiaran a través de tot el que necessiteu per tenir èxit quan torneu a aquest projecte. Si teniu ganes que esteu preparats per continuar, llegiu -ho, a continuació, cobrirem desplegant el vostre codi a un servidor remot i configurar un servidor de correu, a més d'automatitzar el vostre desplegament mitjançant Bash, de manera que sempre podeu configurar un projecte nou amb algunes ordres senzilles.

L'últim que hem de fer abans de desplegar -se a un servidor remot és fer que el nostre lloc sigui una mica més segur. Notareu que la vista d'inici de sessió només té un nom d'usuari i una contrasenya i que no hi ha autenticació multi factor ni un codi de temps. Aquesta és una solució fàcil i, amb el mateix codi, podem fer que el nostre lloc enviï missatges de text i fins i tot respongui als missatges de text enviats al servidor. Per començar, tornarem als models d'usuari i afegirem un signant de marca que representarà cada sessió. També afegirem un identificador únic i rotatiu al model d'usuari que s'utilitzarà per afegir seguretat addicional al nostre inici de sessió. Edició dels models d'usuari, usuaris/models.py, afegiu el codi següent:
# de Models d'importació de django.db
de django.contrib.auth.models importeu usuari
de django.utils Importa el temps de temps
# Assegureu -vos d'importar el Signator de la UUID, el Signatamp i el Generador d'URL (inversa)
importar uuid
de django.core.Signing import Timestamsigner, badsignature, signatureExpirat
de django.urls importen revers

Perfil de classe (models.model):
    user = models.onetoOneField (usuari, on_delete = models.cascade, null = true, en blanc = true, relacionat_name = 'perfil')
    comptabilitat
    last_seen = models.DateTimeField (default = TimeZone.now)
    can_login = models.DateTimeField (default = TimeZone.now)
    preferit_name = models.charfield (max_length = 20, default = '', null = true, en blanc = true)
    bio = models.textField (en blanc = true, default = '')
    # Afegiu aquest codi aquí
    uid = models.charfield (max_length = 32, default = uuid.uuid4, null = true, en blanc = true)
    mfa_enabled = models.booleanField (predeterminat = fals)
    habilita_mfa = models.booleanField (predeterminat = fals)
    phone_number = models.charfield (default = '', null = true, en blanc = true, max_length = 15)
    verification_code = models.charfield (default = '', null = true, en blanc = true, max_length = 15)
    verification_code_length = models.IntegerField (predeterminat = 6)
    mfa_code_expires = models.daTeTimeField (default = TimeZone.now)
    mfa_attempts = models.IntegerField (predeterminat = 0)

    def make_auth_token (self):
        retorn TimestamSamSigner (). Signe (self.uid)

    # I afegiu aquesta funció
    def Create_Auth_Url (self):
        nom d'usuari, token = self.make_auth_token (). dividit (":", 1)
        tornar revers ('usuaris: mfa', kwargs = {'nom d'usuari': nom d'usuari, 'token': token,})

    def check_auth_token (jo, token):
        provar:
            clau = '%s:%s'%(self.uid, token)
            Timestampsigner (). Unsign (clau, max_age = 60 * Settings.Auth_Valid_Minutes) # Vàlid durant 3 minuts
        excepte (badsignature, signatureExpirat):
            tornar fals
        tornar cert
        if user and user.profile.can_login < timezone.now(): # Assegureu -vos d'importar el Signator de la UUID, el signe de marca de temps i el generador d'URL (inversa)
        else: # Afegiu aquest codi aquí
            user = User.objects.filter(username=username).first() # I afegiu aquesta funció
                profile.can_login = timezone.now() + datetime.timedelta(seconds=15) # Vàlid durant 3 minuts
Assegureu -vos que els usuaris/models.py semblen així, a més dels comentaris (codi de les línies amb #). Desglossant -ho, és senzill. Tenim unes quantes importacions, un TimestamSAmSigner que és una utilitat criptogràfica que pot generar un codi segur i verificar -lo per assegurar -se que sigui vàlid, només s'ha utilitzat una vegada i no més gran que un cert nombre de segons. També utilitzem un UUID, que és un identificador únic que identifica el nostre usuari en la signatura del token i a l'URL on s'envia el testimoni a l'usuari. Utilitzarem aquesta criptografia bàsica per crear una vista d'autenticació de dos factors. Abans de fer qualsevol altra cosa, executem les migracions perquè els nostres models d'usuari s'actualitzin. Al directori amb Manage.py, executeu les ordres següents per fer i completar les migracions.

font venv/bin/activeu Python Manage.py Makemigrations && Python Manage.py Migrate

Això és important perquè cada vegada que fem canvis als models, haurem de crear les taules i actualitzar la base de dades amb els valors predeterminats abans que puguem utilitzar els models.

A continuació, improvisem la nostra vista d'inici de sessió per redirigir -nos a una vista d'autenticació secundària. A usuaris/visualitzacions.py, elimineu la funció d'inici de sessió i redirigiu -la a l'URL que acabem de generar als models d'usuari.

# ... importacions DEF Inici de sessió (sol·licitud): si request.method == "POST": nom d'usuari = request.post ['nom d'usuari'] contrasenya = request.post ['contrasenya'] user = autenticate (nom d'usuari = nom d'usuari, contrasenya = contrasenya) Si user i user i user.profile.can_login <Timezone.now (): # Tingueu en compte que ara comprovem si l'usuari pot iniciar la sessió # Elimineu la funció auth_login que hi havia aquí missatges.success (sol·licitud, "la vostra contrasenya s'ha acceptat. Continua.") Si user.profile.mfa_enabled: return redirect (user.profile.create_auth_url ()) # Nota que redirigem a un nou URL aquí Altrament: # Si l'usuari no utilitza l'autenticació de factor mutli, només cal iniciar-les en sessió. auth_login (sol·licitud, usuari, backend = 'django.contrib.auth.backends.modelbackend') RETURNA REDIRECT ("Feed: Feed") Altrament: # Si l'inici de sessió no va tenir èxit, missatges.warning (sol·licitud, "nom d'usuari o contrasenya incorrecte. Torneu -ho a provar.") user = user.objects.filter (nom d'usuari = nom d'usuari) .first () # Aquesta és la part on actualitzem el perfil dels usuaris Si usuari: perfil = user.profile perfile.can_login = timezone.now () + datetime.timedelta (segons = 15) # de manera que no poden tornar a iniciar la sessió durant uns segons perfil.save () return Render (sol·licitud, "usuaris/login.html", {'form': autenticationForm ()})
sudo backup
... Importacions

Tingueu en compte que ara comprovem si l'usuari pot iniciar la sessió

Elimineu la funció auth_login que hi havia aquí
sudo crontab -e
Tingueu en compte que redirigim cap a un URL nou aquí

Si l'usuari no utilitza l'autenticació de diversos factors, només cal que inicieu la sessió.

Si l'inici de sessió no va tenir èxit,
0 * * * * sudo backup
Aquesta és la part en què actualitzem el perfil dels usuaris

Així que no poden tornar a iniciar la sessió durant uns segons

Així que és bastant senzill, ara tenim una manera de redirigir la vista d'autenticació de dos factors quan la creem. També tenim una caiguda en cas que l'usuari no hagi afegit cap número de telèfon. Afegirem una vista bàsica per afegir un número de telèfon aviat i inicieu la sessió amb un missatge de text aviat.

Primer, necessitem una manera senzilla d'enviar un missatge de text des del nostre codi. Per fer -ho, podem triar entre diverses API, però el més fàcil que segons la meva opinió és Twilio. També ofereixen un bon preu per a projectes més petits, així com descomptes a granel. Creeu un compte a Twilio.com, empleneu alguns detalls sobre el vostre projecte, compreu un número de telèfon i copieu les tecles API a la vostra configuració.py. A continuació, afegiu aquest codi sota un fitxer nou, usuaris/sms.py.

usuaris nano/sms.py
sudo visudo
# Importa tots els paquets necessaris de django.utils Importa el temps de temps importar aleatòria Importa dateTime des de la configuració de la importació de django.conf des de Feed.MiddleWare Import Get_Current_Request de django.contrib Missatges d'importació Importa el traçat comptabilitat_sid = Settings.twilio_account_sid auth_token = Settings.twilio_auth_token source_phone = settings.phone_number # Aquest codi envia el text amb Twilio DEF SEND_TEXT (TARGET_PHOPE, TEXT): Des de Twilio.Rest Importa Client provar: client = client (compte_sid, auth_token) Si Len (Target_Phone)> = 11: message = client.messages.create ( a = target_phone, de_ = source_phone, cos = text) excepte: imprimir (trackeback.format_exc ()) # Una funció ajudant per obtenir un número amb tants dígits def get_num_length (num, longitud): n = '' per a x en rang (longitud): n = n + str (num) tornar int (n) # Envieu el text per verificar l'usuari DEF SENT_VERIFICACIÓ_TEXT (usuari): longitud = user.profile.verification_code_lengt code = random.randint (get_num_length (1, longitud), get_num_length (9, longitud)); user.profile.verification_code = codi user.profile.mfa_code_expires = Timezone.now () + dateTime.Timedelta (minuts = 3) user.profile.save () send_user_text (usuari, "El vostre codi de verificació per a {} és {}". format (configurament.site_name, str (codi))))) # Envieu a un usuari qualsevol text amb aquesta funció DEF SEND_USER_TEXT (usuari, text): send_text (user.profile.phone_number, text) # Validar el codi amb aquesta funció def leck_verification_code (usuari, codi): user.profile.mfa_attempts += 1 result = user.profile.verification_code! = none and code! = '' i user.profile.verification_code == code i user.profile.mfa_code_expires> Timezone.now () i user.profile.mfa_attempts <= 3 si user.profile.mfa_attempts <3 i resultat: user.profile.verification_code_length = 6 Elif user.profile.mfa_attempts> 2 i no resultat: user.profile.verification_code_length = 8 user.profile.save () resultat de retorn # Validar l'hora def leck_verification_time (usuari): result = user.profile.mfa_code_expires> Timezone.now () resultat de retorn

Importeu tots els paquets necessaris

Aquest codi envia el text amb Twilio
ALL ALL=NOPASSWD: /bin/backup
Una funció ajudant per obtenir un número amb tants dígits

Envieu el text per verificar l'usuari

Envieu a un usuari qualsevol text amb aquesta funció

Valideu el codi amb aquesta funció

Validar el temps

Assegureu -vos de canviar la configuració adequadament, afegint aquestes línies amb les vostres tecles:

# Assegureu -vos de copiar -les des del vostre tauler Twilio TWILIO_ACCOUNT_SID = "" Twilio_Auth_Token = "" Phone_number = "" Site_name = "" Auth_valid_minutes = 3 # El nombre de minuts La pàgina TFA està activa un cop instantani

Assegureu -vos de copiar -les des del vostre tauler Twilio

El nombre de minuts que la pàgina TFA està activa un cop instantani

Primer, necessitarem formularis per a les nostres dues vistes d'autenticació de factors. Edició d'usuaris/formularis.py, afegiu el codi següent.

# ... importacions de formes d'importació de django # Un formulari per introduir el nostre número de telèfon Class PhonEnumberForm (forms.Form): phone_number = forms.regexfield (regex = r '^\+? def __init __ (jo, *args, ** kwargs): Super (PhonenumberForm, self) .__ init __ (*args, ** kwargs) self.fields ['phone_number']. Label = phone_number_label # Un formulari per autenticar -se Classe TFAFORM (FORMS.Form): codi = form.IntegerField (obligatori = fals) def __init __ (jo, *args, ** kwargs): Super (tfaform, jo) .__ init __ (*args, ** kwargs) self.fields ['codi']. widget.attrs.update ({'autoComplete': 'off'}) help_texts = { "Codi": "Introduïu el codi de sis dígits després d'enviar -lo al telèfon amb el botó de dalt." }
nano app/settings.py
... Importacions

Un formulari per introduir el nostre número de telèfon

Un formulari per autenticar -se

A continuació, creem les visualitzacions en usuaris/visualitzacions.py

# ... importacions de django.http import httpponseredirect des de les formes import phonenumberForm, tfaform Def MFA (sol·licitud, nom d'usuari, token): user = user.objects.filter (perfil__uuid = nom d'usuari) .first () Si no, usuari: return httPresponseredirect (revers ('verify: edat') + '? Next =' + request.get.get ('next') if request.get.get.get ('next') else '/go/' if request.user.is_authenticated i request.user.profile.vendore else '/' if request.user.is_authenticate reverse ('usuaris: login'))))))))) user = get_object_or_404 (usuari, perfil__uuid = nom d'usuari) Següent = request.get.get ("Següent", ")) Si no, user.profile.mfa_enabled: Si no, check_verification_time (usuari): user.profile.mfa_enabled = false user.profile.enable_two_factor_authentication = true user.profile.phone_number = '+1' user.profile.save () Imprimir ("Inici de sessió en l'usuari") auth_login (sol·licitud, usuari, backend = 'django.contrib.auth.backends.modelbackend') missatges.warning (sol·licitud, "Introduïu un número de telèfon vàlid i verifiqueu -lo amb un codi.") return redirect (inversa ('usuaris: mfa_onboarding')))) si request.method == 'post': Forma = TFAFORM (request.post) code = form.data ['codi'] Si codi i codi! = '' i codi! = Cap: token_validated = user.profile.check_auth_token (token) p = user.profile is_verified = check_verification_code (usuari, int (codi)) p.mfa_authenticated = is_verified Si token_validated: Si és_verificat: user.profile.mfa_enabled = true user.profile.save () auth_login (sol·licitud, usuari, backend = 'django.contrib.auth.backends.modelbackend') P.Verfication_code = Cap p.uid = get_uuid () P.Save () missatges.success (sol·licitud, "heu estat autenticats. Benvingut.") QS = '?' per a clau, valor a request.get.items (): qs = qs + key + '=' + valor + '&' si next! = '' i no (next.startswith ('/comptes/logout/') o next.startswith ('/comptes/login/') o next.startswith ('/admin/login/') o nextStartswith ('/comptes/registrat/')): de retorn httPresponseredirect (ext) elif next.startswith ('/comptes/logout/') o next.startswith ('/comptes/login/') o next.startswith ('/comptes/registre/'): RETURNA REDIRECT ("Feed: Feed") Elif request.meta.get ('http_referer', '/').startswith('/accounts/login/'): RETURNA REDIRECT (inversa ("Feed: Feed"))) Elif no següent: RETERIR REDIRECT (inversa ("Feed: Feed") els altres: de retorn httPresponseredirect ("Feed: Feed") els altres: missatges.warning (sol·licitud, "El codi que heu introduït no s'ha reconegut. Torneu -ho a provar.") elif no token_validated: missatges.warning (sol·licitud, "El token de l'URL ha caducat o no s'ha reconegut. Torneu -ho a provar.") sessió (sol·licitud) return redirect (inversa ("usuaris: inici de sessió"))) Si p.mfa_attempts> 3: missatges.warning (sol·licitud, "heu introduït el codi incorrecte més de 3 vegades. Envieu -vos un codi nou.") P.Verification_Code = Cap P.Save () Elif user.profile.can_send_mfa <Timezone.now (): user.profile.mfa_attempts = 0 user.profile.can_send_mfa = timezone.now () + datetime.timedelta (minuts = 2) user.profile.save () send_verification_text (usuari) missatges.success (sol·licitud, "Introduïu el codi enviat al vostre número de telèfon. El codi caducarà en 3 minuts." els altres: Missatges.WARNING (Sol·liciteu, "Envieu massa codis d'autenticació de dos factors. Espereu uns minuts abans d'enviar un altre codi.") forma = tfaform () HADA_LOGO = Cap Si user.profile.hide_logo: hide_logo = cert return Render (sol·licitud, 'usuaris/mfa.html', {'title': 'ENTER CODE', 'FORM': FORM, 'xsmall': true, 'user': usuari, 'hide_logo': hide_logo, 'acl_logout': user.profile.shake_to_logout, 'preload': false}) @Login_Required def mfa_onboarding (sol·licitud): si request.method == 'post': Form = PhonEnumberForm (request.post) request.user.profile.phone_number = form.data ['phone_number']. substituir ('-', '') .replace ('(', ''). substituir (')', '') request.user.profile.mfa_enabled = true request.user.profile.enable_two_factor_authentication = true request.user.profile.save () missatges.success (sol·licitud, "heu afegit un número de telèfon al vostre compte.") user = request.user return redirect (user.profile.create_auth_url ())form = phonenumberForm (inicial = {'phone_number': request.user.profile.phone_number si request.user.profile.phone_number else '+1'}) Return Render (sol·licitud, "usuaris/mfa_onboarding.html", {"title": "Introduïu el vostre número de telèfon", "formulari": format, "petit":
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)
... Importacions

També necessitarem plantilles per a totes dues opinions. Afegim primer la plantilla MFA.

Nano usuaris/plantilles/usuaris/mfa.html
import os
import json
with open('/etc/config.json') as config_file:
    config = json.load(config_file)
Afegiu aquest codi HTML a la plantilla

{ % s'estén 'base.html' %} { % Block Content %} { % de càrrega app_filters %} { % de càrrega crispy_forms_tags %} { % csrf_token %} Introduïu el codi de verificació Pas 1: envieu el codi No compartiu mai el vostre codi amb ningú, ja que es pot utilitzar per accedir temporalment al vostre compte. Enviar codi Pas 2: introduïu el codi {{forma | crispy}} Premeu el botó ENTER per enviar -vos el codi a {{user.profile.phone_number | SecurePhone}}. A continuació, introduïu el codi i premeu Enter. Introduir el codi { % EndBlock %}

Això és bastant explicatiu. El formulari envia un codi o un codi buit i notareu a la vista que enviem el codi si rebem un codi buit. Aleshores només tenim dos botons d'enviament i d'aquesta manera podem enviar el codi amb qualsevol botó. A continuació, afegirem un formulari senzill per afegir un número de telèfon.

usuaris nano/plantilles/usuaris/mfa_onboarding.html

Afegiu el següent html:
sudo nano /etc/config.json
{ % s'estén 'base.html' %} { % Block Content %} { % de càrrega crispy_forms_tags %} { % csrf_token %} Configureu l'autenticació de dos factors {{forma | crispy}} Afegiu el número de telèfon { % EndBlock %}

Aquest formulari és molt més senzill, només proporciona el formulari del número de telèfon que hem creat i permet a l'usuari afegir un número de telèfon.

Això sembla molt bo! Sempre que tot estigui configurat correctament, hauríem de ser capaços d'enviar missatges i iniciar la sessió a l'usuari amb el seu número de telèfon tan aviat com afegim els patrons d'URL. L'últim que hem de configurar és una vista de perfil, de manera que podem assegurar -nos que l'usuari pot canviar el seu número de telèfon sense haver -hi iniciat la sessió. A més, finalment voldrem afegir una opció "Stop to Dye", de manera que l'usuari pugui enviar missatges de text "aturar -se" per optar pels futurs missatges de text.
{
	"EMAIL_HOST_PASSWORD": "<some password here>"
}
Afegim una vista de perfil als usuaris/visualitzacions.py. Aquesta vista actualitzarà la bio, el correu electrònic, el nom d'usuari i el número de telèfon de l'usuari, a més de permetre'ns habilitar l'autenticació de múltiples factors. Primer, necessitarem dos formularis més en usuaris/formularis.py

#... importacions classe userUpdateForm (format.modelform): correu electrònic = format.meilfield () Classe Meta: Model = Usuari fields = ['nom d'usuari', 'correu electrònic'] phone_number_label = 'número de telèfon (no hi ha espais, parèntesi \' (\ 'o taps \'-\ ', números que comencen amb + només)' Classe perfilUpdateForm (formes.modelform): Subscrit = forms.BooleanField (obligatori = fals) phone_number = forms.charfield (obligatori = fals) def __init __ (jo, *args, ** kwargs): Super (perfilUpdateForm, self) .__ init __ (*args, ** kwargs) Classe Meta: Model = perfil fields = ['bio', 'phone_number', 'habile_mfa', 'subscrit']]

... Importacions
nano users/templates/users/verification_email.html
A continuació, podem crear una vista per utilitzar ambdues formes. Editeu usuaris/visualitzacions.py i afegiu -la a la vista.
# Afegiu aquestes importacions des de .Forms import userUpdateForm, perfilUpdateForm de django.views.decorators.cache import Never_cache de django.views.decorators.csrf import csrf_exempt des de .Models Importa perfil de .mfa import send_user_text @csrf_exempt @Never_Cache @Login_Required perfil def (sol·licitud): si request.method == 'post': u_form = userUpDateForm (request.post, instància = request.user) p_form = perfilUpdateForm (request.post, request.files, instància = request.user.profile) si u_form.is_valid () i p_form.is_valid (): new_phone_number = p_form.data ['phone_number'] u_form.save () perfil = p_form.save (commit = fals) perfile.phone_number = perfil.phone_number.replace ('-', '') .replace ('(', ''). substituir (')', '') perfil.save () Si new_phone_number! = OldProfile.phone_number i Oldprofile.phone_number i len (OldProfile.phone_number)> = 11: perfil.mfa_enabled = true perfil.save () send_text (OldProfile.phone_number, "El vostre número de telèfon s'ha actualitzat a ' + new_phone_number +'. Consulteu els textos d'aquest telèfon per iniciar la sessió. Si no heu fet aquest canvi, truqueu -nos. - {} '. Format (Settinged.site_name))) si perfil.enable_two_factor_authentication i perfil.phone_number i len (perfil.phone_number) <11: perfil.enable_two_factor_authentication = false missatges.success (sol·licitud, autenticació del factor F'two no es pot activar sense introduir un número de telèfon. Introduïu un número de telèfon per habilitar l'autenticació de dos factors. ') perfil.save () Si new_phone_number! = OldProfile.phone_number i new_phone_number i len (new_phone_number)> = 11: send_user_text (request.user, "Heu afegit aquest número a {} per a l'autenticació de dos factors. Ara podeu utilitzar el vostre número per a l'autenticació de dos factors. Si no heu fet aquest canvi, truqueu -nos. perfil.mfa_enabled = true perfil.mfa_code_expires = Timezone.now () + dateTime.Timedelta (minuts = 3) perfil.save () return redirect (perfil.create_auth_url ()) missatges.success (sol·licitud, el vostre perfil s'ha actualitzat! ') Imprimir ("perfil actualitzat") Retorna Redirect ("Usuaris: perfil") els altres: u_form = userUpDateForm (instància = request.user) p_form = perfilUpdateForm (instance = request.user.profile, inicial = {'phone_number': request.user.profile.phone_number si request.user.profile.phone_number else '+1'}) context = { 'u_form': u_form, "p_form": p_form, "Títol": "Actualitzeu el vostre perfil", } Return Render (sol·licitud, "usuaris/perfil.html", context)

Afegiu aquestes importacions

També necessitarem una plantilla per a aquesta visió.
SITE_NAME = 'Django App'
PROTOCOL = 'https'
DOMAIN = 'example.com'

BASE_URL = PROTOCOL + '://' + DOMAIN
usuaris nano/plantilles/usuaris/perfil.html

{ % s'estén "base.html" %} { % de càrrega crispy_forms_tags %} {% de càrrega Feed_filters%} { % Block Content %} Edita el teu perfil { % csrf_token %} Informació del perfil {{u_form | crispy}} {{p_form | crispy}} Actualització} Guardat { % EndBlock Content %} { % Block JavaScript %} var form = document.getElementById ('perfil-form'); $ ('entrada'). Canvia (function () { var formdata = nou formadata (forma); $ .aJax ({ URL: window.location.href, Tipus: "Post", Dades: Formdata, ProcessData: fals, ContentType: fals, TIMEOUT: 1000 * 60, èxit: funció (dades) { $ (publicat) .removeclass ("amagar"); setTimeout (function () { $ (publicat) .AddClass ("Fade-Hidden"); setTimeout (function () { $ (publicat) .addclass ("oculta"); $ (publicat) .Removeclass ("Fade-Hidden"); }, 2000); }, 2000); } }); }); { % EndBlock %}

Notareu que és una forma força senzilla, però té algun JavaScript que publica automàticament el contingut del formulari a mesura que s'actualitzen. Això és útil per tenir -ho, de manera que podeu fer edicions sense haver de prémer enviar cada vegada.

A continuació, necessitem URL que representin totes aquestes visualitzacions als usuaris URL Patters. Edita usuaris/urls.py i afegeix aquest codi:

# ... Codi anterior, importacions de django.urls ruta d'importació de. Importa vistes app_name = 'usuaris' urlPatterns = [ # ... patrons d'URL que hem introduït anteriorment, afegiu les tres línies següents ruta ('mfa ///', views.mfa, name = 'mfa'), ruta ('mfa/on boarding/', views.mfa_onboarding, name = 'mfa_onboarding'), ruta ("perfil/", views.profile, name = 'perfil'), ]
nano users/tokens.py
... Codi anterior, importacions

... Patrons d'URL que hem introduït anteriorment, afegiu les tres línies següents

Ara és un bon moment per provar el nostre projecte. Però primer, fem una altra còpia de seguretat.
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()
còpia de seguretat

I executeu el servidor. Abans de desplegar -nos a un servidor Linux, és una bona idea habilitar l'autenticació de dos factors al compte. Ho farem per anar al nostre URL de perfil,/usuaris/perfil/i comprovar la casella per habilitar l'autenticació després d'haver introduït el nostre número de telèfon i, a continuació, enviar el formulari.

Python Manage.py Runserver LocalHost: 8000

Visiteu la pàgina web si aneu al vostre navegador web, estic utilitzant Google Chrome en aquest exemple i introduint l'URL https: // localhost: 8000/comptes/perfil/

Podreu iniciar la sessió si cal i activar l'autenticació de dos factors.
nano users/email.py
Aquest projecte necessita un servidor per executar -lo perquè realment pugui enviar correu. Però primer, necessitem una manera de veure errors. Notareu que si executeu el servidor en mode de depuració, amb Settings.debug igual a True, el servidor mostra errors automàticament. Per mostrar errors sense utilitzar el mode de depuració, que no és segur en un servidor de producció, hauríem d'afegir una vista. Els errors més importants que hem de poder gestionar són:

Error 500: un problema amb el nostre codi Error 404: una pàgina que no es va trobar (URL trencat) Error 403: un error denegat per un permís

Afegim una nova aplicació per gestionar aquests errors, anomenades errors.
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 Manage.py StartApp Errors

Afegiu -ho a la configuració.py com ho vam fer abans, a la configuració de Installed_Apps i comenceu a afegir referències a algunes visualitzacions a APP/urls.py, on l'aplicació és el nom del vostre projecte Django.

Handler404 = 'Errors.Views.Handler404' Handler500 = 'Errors.Views.Handler500' Handler403 = 'Errors.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()
Això és tot el que necessitem, a més de vistes d'error, plantilles i una mica de middleware. Definim -los així:

de django.shortcuts import render, redirect de django.http import httPresponse des de stacktrace.models Error d'importació des de errors.middleware import get_current_exception de django.contrib.auth.decorators importen login_required de django.contrib.auth.decorators import user_passes_test de .logs import get_logs de face.tests import is_superuser_or_vendor de django.views.decorators.csrf import csrf_exempt des de errors.Highlight Importa Highlight_Code de django.shortcuts importen redirect de django.urls importen revers # Creeu les vostres opinions aquí. @Login_Required @user_passes_test (is_superuser_or_vendor) Els registres def (sol·licitud): Logs = Highlight_Code (get_logs ()) Retorn Render (sol·licitud, "Errors/live_error.html", {"títol": "registres d'error", "pagetitle": "logs d'error", "notes": "Aquests són els registres d'errors recents.", "Trace": registres, "Full": True}) @Login_Required @user_passes_test (is_superuser_or_vendor) def logs_api (sol·licitud): Logs = Highlight_Code (get_logs ()) retorn httPresponse (registres) @Login_Required DEF HANDLER404 (sol·licitud, excepció): Si no, request.path.endswith ('/'): return redirect (request.path + '/') Return Render (sol·licitud, "Errors/Error.html", {"Title": "Error 404", "Pagetitle": "Error 404", "Notes": "Aquesta pàgina no s'ha trobat al servidor. Pot ser que s'hagi mogut o s'ha suprimit.", "IS_404": true}) DEF HANDLER500 (sol·licitud): imprimir (get_current_exception ()) Usuari = Cap Si hasattr (sol·licitud, "usuari") i request.user i request.user.is_authenticated: user = request.user provar: Error.Objects.Create (usuari = usuari, stack_trace = get_current_exception (), notes = 'registrat per 500 manipulador.') Excepte: passar Retorn Render (sol·licitud, "Errors/Error.html", {"Title": "Error 500", "Pagetitle": "Error 500", "Notes": "Hi ha un problema amb el servidor o amb una sol·licitud que us prové. Gràcies per la vostra comprensió mentre obtenim les coses configurades. DEF HANDLER403 (sol·licitud, excepció): Retorn Render (sol·licitud, "Errors/Error.html", {"Title": "Error 403", "Pagetitle": "Error 403", "Notes": "No teniu permís per preformar aquesta sol·licitud. Si creieu que això és d'error, poseu -vos en contacte amb l'administrador del servidor.", "IS_403": True}) def handler400 (sol·licitud, excepció): Retorn Render (sol·licitud, "Errors/Error.html", {"Title": "Error 400", "Pagetitle": "Error 400", "Notes": "Aquesta era una mala sol·licitud."})

Creeu les vostres opinions aquí.

A continuació, definim el middleware per gestionar aquests errors. Ho farem afegint primer a middleware_classes a la configuració.py, amb el nom del nostre middleware.

Middleware_classes = [ #... Middleware anterior 'Errors.middleware.ExceptionverBoseMiddleware, ]

... Middleware anterior

A continuació, afegim el middleware.
nano users/models.py
des de la importació de rosca local Importa el traçat de django.utils.deprecation import middlewaremixin _error = local () Class ExceptionVerBoseMiddleWare (MiddleWaremixin): DEF Process_Exception (Self, Sol·licitud, Excepció): _error.Value = Traceback.Format_Exc () def get_current_exception (): provar: tornar _error.Value Excepte Attributeerror: No retorneu cap def set_current_exception (excepció): provar: _error.Value = excepció Excepte Attributeerror: Imprimir ("Excepció de configuració d'error d'atributs.")
# Afegim una funció per obtenir l'excepció actual mitjançant un local de roscat, que ens ajuda a rastrejar qualsevol error al nostre codi. En termes de plantilles, només en necessitem una, perquè definim dinàmicament el títol a la vista. La plantilla només necessita fer el títol i "rastrejar", el nostre traçat d'error des del context.
nano errors/plantilles/errors/error.html

{ % s'estén 'base.html' %} { % Block Content %} {{pagetitle}} {{Trace}} { % EndBlock %}

Aquesta és la nostra plantilla més senzilla, però és tan fàcil veure els errors del nostre projecte. A continuació, desactivem la depuració en la configuració.
# Nano App/Settings.py
            TimestampSigner().unsign(key, max_age=60 * 60 * 24 * 30) # Cerqueu aquesta línia on estigui configurada i canvieu -la per falsa
Depuració = fals

Seguiu endavant i feu una còpia de seguretat de l'aplicació ara. Estem preparats per desplegar -nos a un servidor remot de Linux i seguir afegint funcions a partir d'aquí.

Còpia de seguretat del sudo

Abans de publicar aquest codi a un servidor, hauríem de considerar que hi pot haver alguns problemes amb el codi. Segons el cas, els llocs que accepten informació publicats tindran problemes amb el correu brossa i la dificultat per eliminar el correu brossa. Això no hauria de passar immediatament, però si està passant, examinarem més endavant com moderar automàticament el correu brossa al lloc i farà que els robots accedeixin al lloc, juntament amb com desactivar els comptes d'usuari i verificarà la identitat d'un usuari amb una exploració del seu identificador o una exploració biomètrica, com una empremta o un reconeixement facial.

Veient l'exemple d'autenticació de factors multi -factor que examinem, en producció, les coses poden ser diferents. Observeu com estem limitant la tarifa i que caduquem les fitxes. Si els robots accedeixen a un lloc, l'autenticació de dos factors pot ser més difícil, ja que poden introduir codis alhora que l'usuari ho és. Per combatre -ho, utilitzem un model en els models d'usuari, declarant com interactuem amb el lloc quan estem autenticant mitjançant l'autenticació multi -factor amb un número de telèfon. També afegirem una opció per autenticar -se amb el correu electrònic. Comença editant els models d'usuari amb Nano.
nano users/views.py
usuaris/models nano.py

Això és el que hauria de semblar el model que afegim. No necessitem cap mètode, només variables per emmagatzemar un identificador, l'usuari, la marca de temps, la caducitat, la longitud i els intents contra qualsevol autenticació multi -factor (un codi com 123456 enviat a un telèfon o correu electrònic).

# Un testimoni bàsic que s'utilitza per iniciar la sessió al lloc web Classe mfatoken (models.model): user = models.foreignKey (usuari, on_delete = models.cascade, relacionat_name = 'mfa_tokens') timestamp = models.DateTimeField (default = TimeZone.now) caduca = models.DateTimeField (default = TimeZone.now) token = models.charfield (default = '', max_length = 100) longitud = models.IntegerField (predeterminat = 6) intents = models.IntegerField (predeterminat = 0) uid = models.charfield (default = uuid.uuid4, max_length = 100)
from .email import send_verification_email # Un testimoni bàsic utilitzat per iniciar la sessió al lloc web
Afegim també un privilegi al nostre usuari i el definirem manualment de moment, abans de migrar per allistar els usuaris privilegiats automàticament. Als models d'usuari, afegiu aquesta línia al perfil:

vendor = models.booleanField (default = fals)

Com en qualsevol canvi a la base de dades, hem de fer migracions i migrar la base de dades en qualsevol moment que editem un fitxer Models.py a Django. Recordeu -ho, per fer -ho, utilitzem la font primer (si no s'ha utilitzat ja des que el terminal estava obert) i després Python Manage.py per fer les migracions i migrar.

CD Project-Directory-You amb nom # (si cal) font venv/bin/activeu Python Manage.py Makemigrations && Python Manage.py Migrate

(si cal)
        # De moment, podeu enristar qualsevol compte que hagueu creat com a venedors mitjançant la shell.
    # Python Manage.py Shell
des dels usuaris.models Importa perfil
p = perfil.objects.get (user__userName = 'charlotte')
p.vendor = cert
P.Save ()
sortida ()
# Ara, evolucionem la nostra vista d'autenticació multi -factor per utilitzar aquest token. Primer, hem de modificar els nostres serveis públics de MFA. Utilitzant nano,
usuaris nano/mfa.py

de django.utils Importa el temps de temps importar aleatòria Importa dateTime des de la configuració de la importació de django.conf des de Feed.MiddleWare Import Get_Current_Request de django.contrib Missatges d'importació de .mail import send_html_email Importa el traçat de .models importen mfatoken comptabilitat_sid = Settings.twilio_account_sid auth_token = Settings.twilio_auth_token source_phone = settings.phone_number DEF SEND_TEXT (TARGET_PHOPE, TEXT): Des de Twilio.Rest Importa Client provar: client = client (compte_sid, auth_token) Si Len (Target_Phone)> = 11: message = client.messages.create ( a = target_phone, de_ = source_phone, Body = text + 'Text Stop to cancel.') excepte: missatges.warning (get_current_request (), "Hi va haver un error enviant el missatge.") imprimir (trackeback.format_exc ()) def get_num_length (num, longitud): n = '' per a x en rang (longitud): n = n + str (num) tornar int (n) def Send_verification_text (usuari, token): longitud = user.profile.verification_code_lengt code = random.randint (get_num_length (1, longitud), get_num_length (9, longitud)); token.token = codi token.expires = timezone.now () + datetime.timedelta (minuts = settings.auth_valid_minutes) token.save () send_user_text (usuari, "El vostre codi de verificació per a {} és {}". format (configurament.site_name, str (codi))))) def Send_verification_email (usuari, token): longitud = user.profile.verification_code_lengt code = random.randint (get_num_length (1, longitud), get_num_length (9, longitud)); token.token = codi token.expires = timezone.now () + datetime.timedelta (minuts = settings.auth_valid_minutes) token.save () send_html_email (usuari, "el vostre codi de verificació per a {} és {}". format (Settingsting.site_name, str (codi)), "Dear {}, el vostre codi de verificació per a {} és {}. Gràcies per utilitzar aquest codi per assegurar el vostre compte. {} sincerament, {}". str (codi), settings.site_name)) DEF SEND_USER_TEXT (usuari, text): send_text (user.profile.phone_number, text) def leck_verification_code (usuari, token, codi): token.attempts = token.attempts + 1 perfil = user.profile result = (token! = none and code! = '' i token.Token == Codi i (token.expires> timezone.now ()) i token.attempts <= Settings.mfa_token_attempts) si token.attempts <3 i resultat: perfil.verification_code_length = 6 elif token.attempts> 1 i no resulta: perfil.verification_code_length = perfil.verification_code_lengt si perfil.verification_code_length> Configuració.mfa_token_lengt token.save () perfil.save () resultat de retorn

# Autentica l'usuari mitjançant el seu correu electrònic o número de telèfon Def MFA (sol·licitud, nom d'usuari, usertoken): token = mfatoken.objects.filter (uid = nom d'usuari, expires__gt = timezone.now () + datetime.timedelta (segons = 30)). Order_by ('-Tint Timestamp'). Last () # filtrar el testimoni pel valor passat a l'URL (a UUID) si no és token: token = mfatoken.objects.create (user = user.objects.filter (perfil__uuid = nom d'usuari) .first (), uid = nom d'usuari, caduca = timezone.row () + datetime.timedelta (segons = 115)) # Si aquesta sessió no s'ha creat, creeu -la, creeu -la user = user.objects.filter (id = token.user.id) .first () # Obteniu l'usuari del token Si no, usuari i request.user.is_Authenticated: return redirect (inversa ("feed: casa")) # Si ja estan autenticats, inicieu la sessió Si no, usuari: augmentar el permís () # denegar si no s'ha trobat cap usuari Següent = request.get.get ("Següent", ")) Si no, user.profile.enable_two_factor_authentication i user.is_active i user.profile.check_auth_token (usertoken, token): # Comproveu el token auth auth_login (sol·licitud, usuari, backend = 'django.contrib.auth.backends.modelbackend') # Inicieu la sessió a l'usuari si encara no es connecta user.profile.mfa_expires = timezone.now () + datetime.timedelta (minuts = settings.login_valid_minutes) # Configureu una caducitat a la seva autenticació multi -factor user.profile.save () retorn httPresponseredirect (següent si següent! = '' reverse ('aterratge: desembarcament')) # redirigiu l'usuari a la pàgina següent Si no, user.profile.mfa_enabled: # Comproveu si MFA està habilitada Si no, check_verification_time (usuari, token): # Comproveu l'hora user.profile.mfa_enabled = fals # esborra el número de telèfon user.profile.enable_two_factor_authentication = true # Habilitar MFA user.profile.phone_number = '+1' # Desactiveu el número de telèfon user.profile.save () # Desa el perfil auth_login (sol·licitud, usuari, backend = 'django.contrib.auth.backends.modelbackend') # Inicieu la sessió a l'usuari si el seu MFA no està habilitat missatges.warning (sol·licitud, "Introduïu un número de telèfon vàlid i verifiqueu -lo amb un codi.") return redirect (inversa ('usuaris: mfa_onboarding')))) si request.Method == 'Post' i no Fraud_Detect (Sol·licitud, True): # Si la sol·licitud és una sol·licitud de publicació Form = TFAFORM (request.Post) # Instal·leu el formulari code = str (form.data.get ("codi", cap)) # Obteniu el codi Si el codi i el codi! = '' i el codi! = Cap: # Assegureu -vos que no estigui buit token_validated = user.profile.check_auth_token (usertoken) # Comproveu el token d'autor p = user.profile is_verified = check_verification_code (usuari, token, codi) # Comproveu el codi p.mfa_authenticated = is_verified si token_validated: # si tot si és_verificat: # està en ordre user.profile.mfa_enabled = true # Enable MFA (si no ja està activat) user.profile.save () auth_login (sol·licitud, usuari, backend = 'django.contrib.auth.backends.modelbackend') # Inicieu la sessió a l'usuari face = user.faces.filter (session_key = cap) .Last () p.mfa_expires = timezone.now () + datetime.timedelta (minuts = settings.login_valid_minutes) P.Save () missatges.success (sol·licitud, "heu estat autenticats. Benvingut.") QS = '?' Per a la clau, valor a request.get.items (): # creeu un querystring per al següent paràmetre (si n'hi ha) qs = qs + key + '=' + valor + '&' si next! = '' i no (next.startswith ('/comptes/logout/') o next.startswith ('/comptes/login/') o next.startswith ('/admin/login/') o nextStartswith ('/comptes/registrat/')): de retorn httPresponseredirect (següent) # redirect elif next.startswith ('/comptes/logout/') o next.startswith ('/comptes/login/') o next.startswith ('/comptes/registre/'): RETURNA REDIRECT (inversa ('/')) Elif request.meta.get ('http_referer', '/').startswith('/accounts/login/'): RETURNA REDIRECT (inversa ('/')) Elif no següent: RETURNA REDIRECT (inversa ('/')) els altres: return httPresponseredirect (inversa ('verificar: edat') + '? Next =' + request.meta.get ('http_referer', '/')))) els altres: missatges.warning (sol·licitud, "El codi que heu introduït no s'ha reconegut. Torneu -ho a provar.") elif no token_validated: # si el token no era vàlid missatges.warning (sol·licitud, "El token de l'URL ha caducat o no s'ha reconegut. Torneu -ho a provar.") sessió (sol·licitud) return redirect (inversa ("usuaris: inici de sessió"))) Si p.mfa_attempts> 3: # Si hi hagués massa intents missatges.warning (sol·licitud "han introduït el codi incorrecte més de 3 vegades. Envieu -vos un codi nou. ') P.Verification_Code = Cap P.Save () Elif user.profile.can_send_mfa <Timezone.now (): user.profile.mfa_attempts = 0 user.profile.can_send_mfa = timezone.now () + datetime.timedelta (minuts = 2) user.profile.save () if form.data.get ('send_email', fals): # Envia el correu electrònic (o el text) send_mfa_verification_email (usuari, token) els altres: send_verification_text (usuari, token) missatges.success (sol·licitud, "Introduïu el codi enviat al vostre número de telèfon o correu electrònic. El codi caducarà en 3 minuts.") Elif user.profile.can_send_mfa <Timezone.now () + dateTime.Timedelta (segons = 115): Missatges.WARNING (Sol·liciteu, "Envieu massa codis d'autenticació de dos factors. Espereu uns minuts abans d'enviar un altre codi.") forma = tfaform () HADA_LOGO = Cap Si user.profile.hide_logo: hide_logo = cert if request.user.is_authenticated: return redirect (inversa ('/')) # Rendir el formulari (per obtenir sol·licituds) Retorn Render (sol·licitud, 'usuaris/mfa.html', {'title': 'Enter code', 'form': form, 'xsmall': true, 'user': usuari, 'hidn_logo': hidn_logo, 'acl_logout': user.profile.shake_to_logout, 'preload': false, 'autofocus': request.method ==
nano users/views.py
Autentica l'usuari mitjançant el seu correu electrònic o número de telèfon
# Filtra el testimoni pel valor passat a l'URL (un UUID)
# Si no s'ha creat aquesta sessió, creeu -la
Obteniu l'usuari del testimoni

Si ja estan autenticats, inicieu la sessió

Denegar si no s'ha trobat cap usuari
# Comproveu el testimoni d'autent
            send_verification_email(user) # Inicieu la sessió a l'usuari si encara no es connecta
Estableix una caducitat en la seva autenticació multi -factor

Redirigiu l'usuari a la pàgina següent

Comproveu si MFA està habilitada
# Comproveu l'hora
Esborreu el número de telèfon

Activa MFA

Desactiva el número de telèfon
nano users/templates/users/resend_activation.html
Deseu el perfil

Inicieu la sessió a l'usuari si el seu MFA no està activat

Si la sol·licitud és una sol·licitud de publicació
Instanciant el formulari

Obteniu el codi

Assegureu -vos que no estigui buit
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)
Comproveu el testimoni d'autent

Comproveu el codi

Si tot
Està en ordre

Activa MFA (si no ja està activat)

Inicieu la sessió a l'usuari

Creeu una consulta per al següent paràmetre (si n'hi ha)

Redirigir

Si el testimoni no era vàlid

Si hi hagués massa intents
# Envieu el correu electrònic (o el text)
Rendir el formulari (per obtenir sol·licituds)

Quan afegim en aquest codi, assegureu -vos d'importar la funció per enviar un correu electrònic. A la part superior del fitxer, l'usuari visualitza (amb altres importacions), afegiu -hi

de .mfa import send_verification_email com send_mfa_verification_email
Ara, hem d'escriure aquesta funció abans que tot això funcioni. Hauria d'estendre la nostra funció de correu electrònic d'enviar i simplement enviar un correu electrònic a l'usuari amb el codi de verificació.

usuaris nano/mfa.py

def Send_verification_email (usuari, token): longitud = user.profile.verification_code_lengt code = random.randint (get_num_length (1, longitud), get_num_length (9, longitud)); token.token = codi token.expires = timezone.now () + datetime.timedelta (minuts = settings.auth_valid_minutes) token.save () send_html_email (usuari, "el vostre codi de verificació per a {} és {}". format (Settingsting.site_name, str (codi)), "Dear {}, el vostre codi de verificació per a {} és {}. Gràcies per utilitzar aquest codi per assegurar el vostre compte. {} sincerament, {}". str (codi), settings.site_name))
Així que tot funciona excel·lent, ara tenim un sistema d'autenticació multi -factor que depèn d'un número de telèfon o d'un correu electrònic per iniciar la sessió. Però també necessitem una manera d'eliminar o, com a mínim, ocultar els usuaris que no cooperen amb els nostres termes. Podrien ser spammers, robots o qualsevol persona que no signifiqui bé per a la nostra feina. Doneu una ullada a una vista que tinc per controlar els usuaris al meu lloc web:

# importacions de django.contrib.auth.decorators importen login_required de django.contrib.auth.decorators import user_passes_test des de .Tests import is_superuser_or_vendor # Haurem de crear aquesta prova @Login_Required @user_passes_test (is_superuser_or_vendor) Def usuaris (sol·licitud): # Obteniu la llista d'usuaris new_today = user.objects.filter (is_active = true, date_joined__gte = timezone.now () - datetime.timedelta (hores = 24)). Count () new_this_month = user.objects.filter (is_active = true, date_joined__gte = timezone.now () - dataTime.Timedelta (hores = 24*30)). Compte () Subscribers = user.objects.filter (is_active = true, perfil__subscribed = true) .count () Return Render (sol·licitud, 'usuaris/usuaris.html', { # return usuaris en una plantilla "títol": "tots els comptes", "Usuaris": user.objects.all (), 'new_today': new_today, 'new_this_month': new_this_month, "Subscriptors": subscriptors })

importacions
Haurem de crear aquesta prova

Obteniu la llista d'usuaris

Retornar els usuaris en una plantilla
Tingueu en compte que aquest codi utilitza una prova, haurem de declarar aquesta prova en un fitxer tests.py i importar -lo. Edició d'usuaris/proves.py, creem la prova.

def is_superuser_or_vendor (usuari): return user.profile.vendor o user.is_superuser

Això està conjuntament amb la plantilla usuaris/usuaris.html, que sembla una cosa així:
{ % s'estén 'base.html' %} { % de càrrega app_filters %} { % Block Content %} Tots els visitants registrats {{new_today | nts | capitalitzar}} nou avui, {{new_this_month | nts}} nou aquest mes, {{subscriptors | nts}} subscriptors, {{usuaris.count | nts}} total. { % per a l'usuari en usuaris %} { % inclou 'usuaris/_user.html' %} { % EndFor %} { % EndBlock %}

user.html. Quan s'utilitza una plantilla que tingui un subtemplate i que no s'utilitzi, és una bona idea afegir un baix (

Tingueu en compte que això és una gran quantitat de jinja, és possible que no tingueu totes aquestes variables definides. Però això és el que sembla el meu codi.
    # { % de càrrega app_filters %}


    
      @{{user.userName}} - {{user.profile.name}} ({{user.profile.preferred_name}})
      Última vista {{user.profile.last_seen | data: "f d, y"}} {{user.profile.last_seen | temps: "h: i"}}
      S'ha unit a {{user.profile.date_joined | data: "f d, y"}} {{user.profile.date_joined | temps: "h: i"}}
      {{user.eMail}}
      { % Si user.profile.phone_number %} {{user.profile.phone_number}} { % endif %}
      { % si user.verificacions.last %}
      '{{user.verificacions.last.full_name}}'
       {{user.verificacions.last.document_number}}
       {{user.verificacions.last.birthDate}}
       Identificador
       Torno a tornar
      { % endif %}
      #{{user.id}}
      { % Si user.profile.subscribed %} subscrit { % més %} no subscrit { % endif %}
    
    { %si no user.is_superuser %}
    { % inclou 'usuaris/commulant_active.html' %}
    { % endif %}
    { % autoescape off %}    
    {{user.bio}}
    { % EndautoEscape %}
    
    { % Si user.profile.Identity_verified %} usuari verificat. { % més %} usuari no verificat. { % endif %} verificacions: {{user.verificacions.count | nTS}}
{{user.id}} </small>

També necessitem un altre subtemplate, Toggle_active.html. Aquesta plantilla ha de ser un formulari que ens permeti canviar si un usuari està actiu.

{ % Si user.is_active %} { % més %} { % endif %}

També haurem d'afegir una vista per canviar l'activitat de l'usuari i els patrons d'URL adequats. Mentre hi estem, afegim una vista per eliminar un usuari en cas que ho necessitem.

de django.views.decorators.csrf import csrf_exempt @csrf_exempt @Login_Required @user_passes_test (is_superuser_or_vendor) def toggle_user_active (sol·licitud, pk): user = user.objects.get (id = pk) si request.method == 'post': user.is_active = no user.is_active user.save () return HttPresponse ('' si user.is_active else '') # Importacions de django.contrib.auth.mixins importen loginrequiredmixin, userPassestestMixin des de django.views.Generic Importa DeleteView Class userDeleteView (loginRequiredMixin, userPasseStestMixin, DeleteView): Model = Usuari success_url = '/' # la redirecció de l'URL d'èxit def get_context_data (self, ** kwargs): context = super (). get_context_data (** kwargs) Context de retorn def test_func (self): # test Si l'usuari és superusor i té permís per eliminar user = self.get_object () si self.request.user! = user i self.request.user.is_superuser: tornar cert tornar fals

Importacions

La redirecció de l'URL d'èxit
# Prova si l'usuari és superusor i té permís per eliminar
    # Tot i que això és pràctic quan sigui necessari, suprimir un usuari no hauria de ser necessari la major part del temps, només podem canviar la visibilitat dels usuaris que visiten el lloc si necessitem acomiadar -los.
    # Els patrons d'URL que hem afegit semblen així. Amb Nano, editeu usuaris/urls.py i afegiu aquestes línies:
            TimestampSigner().unsign(key, max_age=60 * settings.AUTH_VALID_MINUTES) # usuaris/urls nano.py
Les línies haurien d'entrar a la llista de rutes de les visualitzacions de l'usuari, abans del final "]", però després del començament "[".

# ... ruta ("usuari // suprimir/", userDeleteView.as_view (template_name = 'blog/user_confirm_delete.html'), name = 'Delete-user'), ruta ('user // actiu/', views.toggle_user_active, name = 'comming-user-actiu'), # ...

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

Ara, assegureu -vos de fer una còpia de seguretat del lloc perquè pugueu descarregar -lo al servidor web on continuarem treballant. Des de la línia d'ordres,

Còpia de seguretat del sudo

Ara el nostre lloc està recolzat.

Així que ara tenim algunes funcions més útils. Però, què passa amb la gran imatge aquí? Aquest codi encara no és accessible des d'Internet, encara no tenim servidor de correu i hem d'ampliar la nostra aplicació per incloure un procés de verificació complet, així com dissenys suaus per ajudar -nos a explorar el lloc, juntament amb protocols segurs per autenticar usuaris privilegiats.
# Arribarem a tot això. El més important per ara només serà aconseguir aquest codi en línia, cosa que podem fer amb només algunes línies de bash en un servidor Ubuntu. Tanmateix, haureu de llogar un servidor, tret que tingueu un servidor a casa i una subscripció a Internet de negocis que us permeti obrir ports. Executo personalment el meu lloc web en un HP Z440 instal·lat al meu apartament, però normalment és molt més barat per a les necessitats bàsiques de llogar un servidor privat virtual (VPS).
        if user and user.profile.can_login < timezone.now(): # Tingueu en compte que el codi que estem executant ara és relativament prim, caldrà mantenir i millorar abans que estiguem a punt per utilitzar el que hem de crear un producte. Assegureu -vos d'anar amb compte de què feu amb Internet, assegureu -vos que si desplegueu aquest lloc públicament a la web d'un servidor Linux, teniu un pla per bloquejar les interaccions no desitjades amb el vostre lloc web. Probablement això no serà un problema al principi, però examinarem diverses solucions per combatre -ho, com ara l'aprenentatge automàtic, la intel·ligència artificial i la visió informàtica. Quan es converteixi en un problema, busqueu més aquest text una solució.
            # Pel que fa a llogar un VPS, hi ha molts llocs que podeu anar. Google Cloud compta amb servidors VPS, Ionos, Kamatera, Amazon AWS i més proveïdors ofereixen solucions de servidor Cloud que s'adapten a les nostres necessitats.
                return redirect(user.profile.create_auth_url()) # Haureu de fer clic a través dels seus formularis i seleccionar un pla per començar. Podeu anar amb un pla bàsic amb qualsevol proveïdor, però assegureu -vos que el proveïdor us permet obrir els ports del servidor de correu de port per enviar correu electrònic (aquest ha de ser el port 587 i el port 25), alguns proveïdors bloquegen aquests ports. Fins ara he tingut la millor experiència amb Ionos i Kamatera, tots dos em permetran enviar un correu electrònic il·limitat i els seus preus són força barats.
            else: # Us connectareu al vostre nou servidor a través d'un protocol anomenat SSH o Secure Shell, que us permet interferir de forma remota amb el servidor exactament com el vostre ordinador personal, des del vostre ordinador personal. Quan configureu el servidor, és probable que el proveïdor d'allotjament us demani que afegiu una clau SSH o que us donarà un nom d'usuari i una contrasenya. La clau SSH és com iniciaràs la sessió al servidor des de la línia d'ordres per editar el codi. Utilitzeu les opcions següents de SSH-KeyGen per generar una clau SSH.
        else: # ssh-keygen
            user = User.objects.filter(username=username).first() # Deseu el fitxer i sobreescriviu -lo si ho necessiteu, és bo girar les tecles SSH si encara no ho heu fet. Ara, podeu utilitzar la següent comanda per veure la vostra clau SSH. Voldreu copiar -lo al vostre servidor remot perquè pugueu utilitzar -lo per autenticar -lo.
                profile.can_login = timezone.now() + datetime.timedelta(seconds=15) # cat ~/.ssh/id_rsa.pub
Si no heu pogut veure una clau SSH quan escriviu aquesta ordre (una llarga cadena de dígits i lletres que comencen amb "SSH-RSA AAA"), proveu de generar una clau RSA (són més segures, per la qual cosa aconsello que els utilitzi.) El codi següent generarà una clau SSH de 4096 bits.

SSH -KEYGEN -T RSA -B 4096

Creeu un VPS amb Ubuntu, però teniu previst fer -ho. Un cop hàgiu creat un VPS fent clic als formularis del lloc web dels proveïdors (kamatera.com, ionos.com o similar), voldreu iniciar la sessió. Per fer -ho, utilitzeu l'ordre SSH amb la vostra adreça IP (l'adreça que sembla xx.xx.xx.xx). També haureu de ser sensibles al nom d'usuari predeterminat del servidor que hem creat, per exemple, Ubuntu.

ssh ubuntu@xx.xx.xx.xx

Podeu demanar -vos una contrasenya, si se us demana una contrasenya, introduïu -la. No utilitzarem el nom d'usuari predeterminat, així que comencem creant un nou usuari i afegint una clau SSH al seu compte.
nano users/sms.py
Comencem per afegir un nou fitxer sshd_config, que indica al servidor com utilitzar SSH.
# nano sshd_config
# # Aquest és el fitxer de configuració del sistema SSHD a tot el sistema.  Veure
# SSHD_CONFIG (5) Per obtenir més informació.

# Aquest SSHD es va compilar amb ruta =/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/jocs

# L'estratègia que s'utilitza per a les opcions del SSHD_CONFIG per defecte enviat amb
# OpenSSH és especificar les opcions amb el seu valor per defecte on
# Possible, però deixeu -los comentar.  Les opcions sense notar anul·len el
# valor per defecte.

#Port 22
#Addressfamily qualsevol
#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

# Xifres i claus
#RekeyLimit per defecte Cap

# Registre
#SyslogFacility Auth
Informació de #loglevel

# Autenticació:

#Logingracetime 2m
#PermitrootLogin prohibit-pasword
#StrictModes sí
#Maxauthtries 6
#MaxSessions 10

PubKeyAuthentication Sí

# Espereu que .SSH/Autoritzat_KEYS2 es ignori de manera predeterminada en el futur.
AutorizedKeysFile .SSH/Autoritzat_KEYS .SSH/AUTORITY_KEYS2

#AuthoredPrincipalsFile Cap

#AuthoredKeysCommand Cap
#AuthoredKeysCommanduser Ningú

# Perquè això funcioni, també necessitareu claus d'amfitrió a/etc/ssh/ssh_known_hosts
#HostBasedAuthentication núm
# Canvieu a sí si no confieu ~/.SSH/conegut_Hosts
# HostBasedAuthentication
#IgnoreUserHoblehosts núm
# No llegiu els fitxers de l'usuari ~/.rhosts i ~/.shosts
#IgnorerHosts sí

# Per desactivar les contrasenyes de text clares de Tunnel, canvieu -hi cap aquí!
Authenticació de contrasenya núm
#Permitemptypasswords no

# Canvieu a Sí per habilitar les contrasenyes de resposta a Challenge (tingueu en compte els problemes
# alguns mòduls i fils PAM)
KbdinteractiveAuthentication núm

# Opcions de Kerberos
#KerberosAuthentication núm
#Kerberosorlocalpasswd sí
#Kerberosticketcleanup sí
#Kerberosgetafstoken núm

# Opcions GSSAPI
#Gssapiauthentication núm
#GssapicLeanupcredentials sí
#Gssapistricticcceptorcheck sí
#Gssapikeyexchange núm

# Configureu -ho a "Sí" per habilitar l'autenticació PAM, el processament de comptes,
# i processament de sessió. Si això està activat, l'autenticació PAM ho farà
# es pot permetre a través de la KBdInteractiveAuthentication i
# PasswordAuthentication.  Segons la vostra configuració PAM,
# PAM Autenticació mitjançant kbdInteractiveAuthentication pot passar per alt
# La configuració de "permissorootlogin sense paraula".
# Si només voleu que el compte PAM i les comprovacions de sessió funcionin sense
# Pam Autenticació i, a continuació, activeu -ho, però configureu la connexió Authentication
# i kbdInteractiveAuthentication a "no".
USEPAM Sí

#AllowAgentForwarding Sí
#Allowtcpforwarding sí
#Gatewayports núm
X11Forwarding sí
#X11displayoffset 10
#X11uselocalhost sí
#Permittty sí
Imprimirmotd núm
#Printlastlog sí
#Tcpkeepalive sí
#PermitUserEnvironment núm
#COMPRESSION retardat
#ClientiveInterval 0
#ClientAlivecountMax 3
#Usedns no
#Pidfile /run/ssshd.pid
#MaxStartups 10: 30: 100
#PermitTunnel núm
#ChrootDirectory Cap
#VersionAddendum Cap

# No hi ha cap ruta de bandera per defecte
Banner /etc /Banner

# Permet al client passar variables d'entorn local
Acceptenv Lang Lc_*

# Substitució per defecte de Sense subsistemes
Subsistema SFTP/USR/LIB/OPENSH/SFTP-SERVER

# Exemple de la configuració de sobrealimentació de forma per usuari
#Match usuari anoncvs
# X11forwarding núm
# Permettcpforwarding núm
# Permitty no
# ForceComand CVS Server
PermetOroTlogin núm
# Aquest és el fitxer de configuració del sistema SSHD a tot el sistema.  Veure
# SSHD_CONFIG (5) Per obtenir més informació.
# Aquest SSHD es va compilar amb ruta =/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/jocs
# L'estratègia utilitzada per a les opcions del sshd_config per defecte s'envia amb
# OpenSSH és especificar les opcions amb el seu valor predeterminat on
Possible, però deixeu -los comentar. Les opcions sense notar anul·len el

valor per defecte.

Port 22
# Adreçafamily qualsevol
AUTH_VALID_MINUTES = 3 # Escolta 0.0.0.0.0
Escolta ::

HOSSKEY/ETC/SSH/SSH_HOST_RSA_KEY

HOSSKEY/ETC/SSH/SSH_HOST_ECDSA_KEY
# Hostkey/etc/ssh/ssh_host_ed25519_key
# Xifres i claus
# RekeyLimit per defecte Cap
Registre

SyslogFacility Auth

Informació de Loglevel
# Autenticació:
Logingracetime 2m

PermetoRootLogin prohibit-pasword

Strictmodes sí
nano users/templates/users/mfa.html
MaxAuthtries 6

MaxSessions 10

Espereu que .SSH/Autorized_Keys2 es ignori de manera predeterminada en el futur.
AutorizedPrincipalsFile Cap

AutoritzatKeysCommand Cap

AutoritzatKeysCommanduser Ningú
nano users/templates/users/mfa_onboarding.html
Perquè funcioni, també necessitareu claus d'amfitrió a/etc/ssh/ssh_known_hosts

HostBasedAuthentication núm

Canvieu per sí si no confieu ~/.SSH/conegut_Hosts
HostBaseAuthentication

IgnoreUser coneguthosts núm

No llegiu els fitxers de l'usuari ~/.rhosts i ~/.shosts

Ignorerhosts sí

Per desactivar les contrasenyes de text clares de Tunnel, canvieu -hi cap aquí!

PermetImpAsswords núm.

Canvieu a Sí per habilitar les contrasenyes de resposta a Challenge (tingueu en compte els problemes
# Alguns mòduls i fils PAM)
Opcions de Kerberos

KerberosAuthentication núm

Kerberosorlocalpasswd sí
# Kerberosticketcleanup sí
Kerberosgetafstoken núm

Opcions GSSAPI

GSSAPIAUTHENTICACIÓ núm
nano users/templates/users/profile.html
GSSAPICLEANUPCREDENCIALS SÍ
GSSAPistriccceptorCheck sí

GSSAPIKEYEXCHANGE NO

Configureu -ho a "Sí" per habilitar l'autenticació PAM, el processament de comptes,

i processament de sessió. Si això està activat, l'autenticació PAM ho farà

es pot permetre a través de la KBdInteractiveAuthentication i
# Authenticació de contrasenya.  Segons la vostra configuració PAM,
# L'autenticació PAM mitjançant KBDInteractiveAuthentication pot passar per alt
La configuració de "permissorootlogin sense pas de paraula".

Si només voleu que el compte PAM i les comprovacions de sessió s'executin sense

Autenticació PAM i, a continuació, activeu -ho, però configureu PasswordAuthentication
backup
i kbdInteractiveAuthentication a "no".

AllowAgentForwarding sí

Permettcpforwarding sí
python manage.py runserver localhost:8000
GatewayPaports núm

X11displayoffset 10

X11Uselocalhost sí

Permitty sí

Printlastlog sí

Tcpkeepalive sí

PermetUserAnvironment núm

Compressió endarrerida

ClientAliveInterval 0

ClientAliveCountMax 3

Usedns núm
python manage.py startapp errors
Pidfile /run/ssshd.pid

MaxStartups 10: 30: 100

PermitTúnel núm
handler404 = 'errors.views.handler404'
handler500 = 'errors.views.handler500'
handler403 = 'errors.views.handler403'
Chrootdirectory none

VerseAddendum Cap

No hi ha cap ruta de bandera per defecte
# Permet al client passar variables d'entorn local
Substitució per defecte de No Subsistemes

Exemple de paràmetres anteriors de forma per usuari

Coincideix amb els anoncvs de l'usuari
    # X11forwarding núm
Permettcpforwarding núm

Permitty núm

ForceComand 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.')
Recordeu -vos que Ctrl+X i Y per desar el fitxer. A continuació, escrivim un script bàsic anomenat Inicialització (tot al directori domèstic predeterminat del nostre usuari).

Nano inicialitza

Amb la vostra clau SSH, heu trobat amb CAT. (.SSH/ID_RSA.PUB)
nano errors/templates/errors/error.html
#!/bin/bash Sudo Apt Install -Y Nano Git OpenSh -Server sudo cp sshd_config/etc/ssh/sshd_config Sudo Service SSH Reinicieu SUDO SERVEI SSHD RESTAR eco "/root/.ssh/id_rsa" | sudo su arrel -c "ssh -keygen -t rsa -n ''" eco "Root ssh clau:" SUDO SU ROOT -C "CAT /ROT/.SSH/ID_RSA.PUB" Sudo Adduser-Disabled-Password --Gecos "" Equip Sudo Passwd -Team SUDO USERMOD -Ag Sudo Team eco "/home/team/.ssh/id_rsa" | SU Team -C "SSH -KEYGEN -T RSA -N ''" CAT /HOME/TEAM/.SSH/ID_RSA.PUB >> /home/team/.ssh/authored_keys eco '' >> /home/team/.ssh/authored_keys Echo "Team SSH Key:" Cat /home/team/.ssh/id_rsa.pub
!/bin/bash

Per caminar per aquest fitxer, comencem la línia per línia. La primera línia diu al compilador que es tracta d'un guió de Bash. A continuació, instal·lem dependències, copiem SSHD_CONFIG al directori correcte, reiniciem SSH, generant tecles SSH per a ROOT, afegint l'usuari "equip" (podeu triar un nom que us agradi per a això, utilitzeu l'ordre Adduser amb el seu nom i la contrasenya desactivada per ara). També afegim equip al grup sudo, generem la seva clau SSH, afegim la nostra clau a les claus autoritzades i les seves i imprimir la seva clau. Aquest nou usuari serà com iniciem la sessió al lloc.

En un nou terminal, aneu endavant i obriu el servidor de nou.
nano app/settings.py
ssh equip@xx.xx.xx.xx

Aquesta vegada no hauríeu de necessitar una contrasenya, ja que teniu una clau SSH. També hem desactivat l'inici de sessió amb contrasenya per mantenir el lloc més segur.

Ara, aquest servidor comença completament en blanc sense informació. Comencem per clonar el nostre projecte des de Git per poder descarregar -lo i executar -lo a la màquina remota. Al servidor remot connectat a través de SSH, imprimiu primer la vostra clau SSH:
DEBUG = False
cat ~/.ssh/id_rsa.pub

A continuació, enganxeu aquesta clau a la configuració de Git com ho vam fer abans per configurar el nostre dipòsit Git. Ara podem clonar el nostre projecte directament al servidor. Assegureu -vos que heu fet una còpia de seguretat del projecte localment primer, de manera que es descarregui al servidor Git.

git clon git: //github.com/you/yourproject.git
sudo backup
Perfecte. Ara tots els fitxers són aquí. Els podem veure amb LS

ls

Ara, comencem a configurar el servidor. Primer, copieu el vostre directori de projectes amb un nom senzill i memorable que utilitzarem per al projecte.

cp -r el vostre propòsit whatyoucalledit

On "whatyoucalledit" és el nou nom del vostre projecte. A continuació, haurem de crear una utilitat bàsica per configurar el servidor. Estalviarem aquesta utilitat i l'utilitzarem en el futur. Per crear aquesta utilitat, creem un binari d'usuari per definir com editem un script. Utilitzant Bash, Edita/USR/Bin/Ascript
nano users/models.py
sudo nano/usr/bin/ascript

Assegureu -vos d'utilitzar el sudo allà perquè tingueu permisos per editar el fitxer. Al fitxer, afegiu aquestes línies:

#!/bin/bash Si [! -f/usr/bin/$ 1]; llavors Sudo Touch/USR/Bin/$ 1 eco "#!/bin/bash" >>/usr/bin/$ 1 sudo chmod a+x/usr/bin/$ 1 sudo nano/usr/bin/$ 1 eco 1 $ | SUDO TEE -A /ETC /ASCRIPTS qualsevol sudo chmod a+x/usr/bin/$ 1 sudo nano/usr/bin/$ 1 fi
# !/bin/bash
!/bin/bash ">>/usr/bin/$ 1

Recordeu que aquest script pren un argument, el nom del script, com a $ 1. Primer comprova si el fitxer existeix o el crea d'altra manera, afegeix la primera línia per declarar que l'script és bash, canvia els seus permisos, l'edeix i afegeix el seu nom a /etc /Ascripts que ens permet emmagatzemar els noms dels scripts que estem creant. Si el fitxer ja existeix, simplement canvieu els permisos i editeu -lo. Deseu el fitxer i, a continuació, canviarem els seus permisos. Sempre que utilitzem aquest guió, no haurem de tornar a fer -ho.

sudo chmod a+x/usr/bin/ascript
    vendor = models.BooleanField(default=False)
Perfecte. Ara creem un script anomenat Configuració. Primer, per no aclaparar -vos, però feu una ullada a com és el meu guió de configuració. Caminarem pel que hauria de semblar aquest guió en el vostre projecte, no necessitareu tot el meu guió per començar.

#!/bin/bash Segons = 0 Python_version = 3.12 ECHO "Instal·lador Femmebabe Inicialitzat." # SUDO CHMOD A+X Scripts/Usersetup # ./scripts/usersetup # ssh-keygen # Directori de projectes Dir = "/home/equip/femmebabe" User = "equip" # Ordres de registre eco "Comandes de registre" Sudo cp log/commands.log /var/log/commands.log sudo chmod -r a+w /var /log Sudo Chown -r: syslog /var /log eco $ 'àlies venv = "font/home/equip/femmebabe/venv/bin/activar"' | SUDO TEE -A /HOME/TEAM/.Profile eco $ 'prompt_command = \' retrn_val = $?; logger -p local6.debug "$ (whoami) [$$]: $ (History 1 | sed" s/^[]*[0-9] \+[]*// ")" \ '' | SUDO TEE -A /ETC /BASHRC eco $ 'prompt_command = \' retrn_val = $?; logger -p local6.debug "$ (whoami) [$$]: $ (History 1 | sed" s/^[]*[0-9] \+[]*// ")" \ '' | Sudo Tee -A "/home/team/.bashrc" eco $ 'prompt_command = \' retrn_val = $?; logger -p local6.debug "$ (whoami) [$$]: $ (History 1 | sed" s/^[]*[0-9] \+[]*// ")" \ '' | Sudo tee -a /root/.bashrc eco "font /etc /Bashrc" | SUDO TEE -A /HOME/TEAM/.Profile eco "/var/log/commands.log" | Sudo Tee -A /etc/logrotate.d/syslog eco "local6.* /var/log/commands.log" | Sudo Tee -A "/etc/rsyslog.d/bash.conf" SUDO SERVEI RSYSLOG RESTAR # Nano Config eco "Set Tabsize 4" >> .nanorc eco "Set Tabstospaces" >> .nanorc # Git Config eco "Configuració git" 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 /ROT/.SSH/BOWN_HOSTS SUDO SSH -KEYSCAN -T RSA GitHub.com | SUDO TEE -A /ROT/.SSH/BOWN_HOSTS eco "Configuració de muntatge" Sudo Mount -O Remount, Size = 16G, Exec /TMP # Actualitzar i instal·lar eco "Actualitzar i instal·lar paquets" Sudo apt Update && Sudo NeedRestart_Mode = una actualització apta -y Sudo apt purge postgresql-client-14 postgresql-client-common postgresql-common postgresql-contrib postgresql -y ECHO "Postfix Postfix/MailName String Femmebabe.com" | SUDO DEBCONF-SELECCIONS eco "postfix postfix/main_mailer_type string" lloc d'Internet "" | SUDO DEBCONF-SELECCIONS Sudo NeedRestart_Mode = A Debian_Frontend = APT no interactiu INSTAL·LACIÓ -Y POSTFIX Sudo NeedRestart_Mode = Una instal·lació apta -y rkhunter Clamav-daemon libx264-dev ffmpeg libapache2-mod-wsgi-py3 apache2 cmake python-is-python3 python3-venv python3-pip python3-django espera tesseract -ococ libopencv-dev python3-openencv python3-dev libsasl2-dev opendkim opendkim-tools dovecot-core dovecot-pop3d dovecot-imapd procil Python3-CERTBOT-Apache eco "-a sortida, sempre -f arch = b64 -f euid = 0 -s execve" | Sudo Tee -A /etc/audit/audit.rules eco "-a sortida, sempre -f arch = b32 -f euid = 0 -s execve" | Sudo Tee -A /etc/audit/audit.rules # Habilita l'antivirus de Clamav eco "Començar antivirus" SUDO Systemctl Habilita CAMAV-Daemon SUDO Systemctl Start Clamav-Daemon # Configureu el nom d'amfitrió eco "127.0.0.1 Femmebabe" | Sudo Tee -A /etc /amfitrions sudo hostnamectl set-hostname localhost # Postgres de configuració eco "Postgres Configuració" SUDO -U POSTGRES PSQL -U POSTGRES -C "Base de dades de bases de dades Drop;" SUDO -U POSTGRES PSQL -U POSTGRES -C "Creeu base de dades de bases de dades;" SUDO -U POSTGRES PSQL -U POSTGRES -C "Creeu l'usuari django amb contrasenya" contrasenya ";" SUDO -U POSTGRES PSQL -U POSTGRES -C "Alter Role Django SET CLIENT_ENCODING a" UTF8 ";" SUDO -U POSTGRES PSQL -U POSTGRES -C "Alter Role Django Set Default_Transaction_Isolation a" Llegir compromès ";" SUDO -U POSTGRES PSQL -U POSTGRES -C "Alter Role Django Estableix la zona horària a" UTC ";" SUDO -U POSTGRES PSQL -U POSTGRES -C "concedeix tots els privilegis a la base de dades de bases de dades a django;" # Còpia de seguretat de la base de dades de configuració ECHO "Basat de dades de la còpia de seguretat, pot trigar un temps". Cat db.json. ?? > db.json eco "Configuració del tallafoc" Sudo ufw predeterminat permet sortir sudo ufw predeterminat denega entrant Sudo ufw permet 22 Sudo ufw permet http Sudo ufw permet https Sudo ufw permetre "postfix" Sudo ufw permetre "postfix smtps" Sudo ufw Permet la "submissió de postfix" sudo ufw permetre "Dovecot pop" Sudo ufw Permet "Dovecot Secure Pop3" Sudo ufw permet 110/tcp Sudo ufw Permet 25/TCP eco "y" | Sudo UFW Habilit # Desactivar iptables eco "Configuració del tallafoc" Sudo Iptables -P Accepta acceptar SUDO IPTABLES -P OUTPUT ACCEPTA Sudo iptables -p Forward accepta sudo iptables -f Sudo Iptables-Save # Instal·leu BitDefender CD $ DIR ECHO "Instal·lador antivirus de Runnning BitDefender" 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/instal·lador sudo chmod a+x bitdefender/instal·lador sudo ./bitdefender/installer # Configuració postfix CD $ DIR ECHO "Configuració dels serveis de correu" " 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/ETC_DOVECOT_CONF.D_10-AUTH.CONF /TC/DOVECOT/CONF.D/10-AUTH.CONF SUDO CP CONFIG/ETC_DOVECOT_CONF.D_10-MASTER.CONF /TC/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/TLEES sudo mkdir /etc/opendkim/keys/femmebabe.com sudo mkdir/var/spool/postfix/opendkim Sudo eco "*@femmebabe.com sendonly._domainkey.femmebabe.com" | SUDO TEE -A /TC/OPENDKIM/SIGNING.TABLE Sudo eco "sendonly._domainkey.femmebabe.com femmebabe.com:sendonly:/etc/opendkim/keys/femmebabe.com/sendonly.private" | SUDO TEE -A /TC/OPENDKIM/KEY.TABLE Sudo eco "127.0.0.1" | Sudo Tee -A /etc/opendkim/trusted.hosts Sudo eco "localhost" | Sudo Tee -A /etc/opendkim/trusted.hosts Sudo eco "" | Sudo Tee -A /etc/opendkim/trusted.hosts Sudo eco "*.femmebabe.com" | Sudo Tee -A /etc/opendkim/trusted.hosts Sudo Chown -r Opendkim: Opendkim /etc /opendkim sudo opendkim -generkey -b 2048 -d femmebabe.com -d /etc/opendkim/keys/femmebabe.com -s Sendonly -v SUDO CHMOD GO-RW/etc/Opendkim/Tecles 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/mail/ Sudo Chown: usuaris/var/mail/* sudo chmod -r a+rwx/var/mail/* SUDO Systemctl Reiniciar Opendkim Postfix Dovecot # Crea dirs CD $ DIR Mkdir Media/Àudio MKDIR Media/Audio/Introduïdes dactilars Mkdir Media/Seguretat Mkdir Media/Secure Mkdir Media/Secure/Media Mkdir Media/Secure/Video Mkdir Media/Secure/Perfil Mkdir Media/Secure/Face Mitjà/Imatges de Mkdir Mkdir Media/Live mkdir media/live/fitxers Mkdir Media/Live/Stills mkdir suports/fitxers Mkdir Temp Mkdir Temp/dades mkdir temp/gfpgan Mkdir Mail/Inbox bústia de mkdir # Configuració VirtualEnv CD $ DIR eco "Creació d'entorn virtual" python -m venv venv font venv/bin/activeu # Obtenir i crear dependències Echo "obtenir i crear dependències, això pot tenir un malestar" CD $ DIR git clon https://github.com/sukhitashvili/violence-detection.git CP Config/VD-Requirements.txt Violence-detection/requisits.txt CP Config/VD-MODEL.PY Detecció de violència/model.py Detecció de violència de CD PIP3 Instal·lació -r requisits.txt CD $ DIR wget https://github.com/tencentarc/gfpgan/releases/download/v1.3.0/gfpganv1.3.pth -p Experiments/pretrained_models Git Clon https://github.com/tencentarc/gfpgan.git git clon https://github.com/davisking/dlib.git cd dlib Mkdir Build; CD construcció; cmake ..; Cmake -Build. CD .. font venv/bin/activeu Python Setup.py Instal·lació CD $ DIR font venv/bin/activeu CD $ dir/gfpgan/ eco "Instal·lació de dependències de Python" PIP instal·la Basicsr pip install facExlib PIP install -r requisits.txt Python Setup.py desenvolupar PIP instal·la Realesrgan CD $ DIR SUDO CHOWN -R TEAM: usuaris GFPGAN eco "Instal·lació de ta-lib" Wget https://prownloads.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 ./Configura Sudo Make Sudo Make Install # Estableix les regles del tallafoc CD $ DIR # Instal·leu les dependències PYPI eco "Instal·lar les dependències de Python restants (això pot trigar una estona)" màscara SUDO Systemctl tmp.mount CD $ DIR font venv/bin/activeu PIP3 instal·la -u "api [redis]" PIP3 Install -r requisits.txt --use-deprecated = Legacy-resolver --use-Pep517 PIP3 Instal·lació --Upgrade OpenCV-Python #== 4.5.4.60 Pip3 Install --Upgrade OpenCV-Contrib-Python #== 4.5.4.60 #PIP Install OpenCV-Python == 4.5.5.64 #PIP Install OpenCV-Contrib-Python == 4.5.5.64 PIP3 Instal·lació --Upgrade OpenCV-Python-Head-Headless PIP3 Desinstal·la els canals PIP3 desinstal·la Daphne PIP3 Instal·leu els canals ["Daphne"] PIP3 instal·la el coixí == 9.5.0 pip3 instal·la librosa PIP3 Instal·lació -u 'Twisted [tls, http2]' PIP3 Instal·lació --Upgrade Certifi Sol·licituds Urllib3 Numpy Oauthlib Twisted Pyjwt SqlParse Cryptografia Astral WebAuthn DocbarCodes pdf417 Deepface --no-cache-sur PIP3 instal·la tensorFlow == 2.15.1 # Instal·leu el certbot eco "Instal·lació de certificats" Sudo Snap Install Core; Sudo Snap Refresh Nucly Sudo Snap Install -Clàssic Certbot sudo ln -s/snap/bin/certbot/usr/bin/certbot Sudo Snap Install Redis SUDO Systemctl Activa Apache2 SUDO Systemctl Start Apache2 # Run Certbot SUDO CERTBOT --APACHE --NON-INTERICTIVE --regree-tos --domains femmebabe.com --Email jasper.camber.holton@gmail.com # Torneu a carregar el servidor de correu SUDO Systemctl Reiniciar Opendkim Postfix Dovecot # CERTS DE COPA #sudo cp /etc/letsencrypt/live/femmebabe.com/privkey.pem privada.pem #sudo cp /etc/letsencrypt/live/femmebabe.com/cert.pemh venv CP Scripts/Content.py $ "/home/equip/femmebabe/venv/lib/python $ {python_version} /site-packages/pyxb/binding/content.py" scripts cp/pwa_webpush_forms.py $ "/home/equip/femmebabe/venv/lib/python $ {python_version} /site-packages/pwa_webpush/forms.py" CP Scripts/WebAuth_Views.py $ "/home/equip/femmebabe/venv/lib/python $ {python_version} /site-packages/webauth/views.py" scripts cp/json.py $ "venv/lib/python $ {python_version} /site-packages/django/core/serializers/json.py" # Configureu la configuració de l'usuari SUDO GPASSWD -A WWW -DATA # Estableix els permisos eco "Configuració de permisos" SUDO CHOWN -R EQUIP: CACHE DE CACH/ ESTUDIANTS/ SUDO CHMOD A+RWX -R CACHE/ #sudo chown -r equip: usuaris/var/run/ #sudo root root: arrel/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 Equip: usuaris/var/log/ Sudo Chown -r: usuaris .././ 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: usuaris db.sqlite3 Sudo Chown -r www-data: www-data media/ Sudo Chown www-data: usuaris ./ SUDO CHOWN -R EQUIP: USUS Media/ SUDO CHOWN -R Team: usuaris ./ SUDO CHOWN -R Team: usuaris ./gfpgan/ SUDO CHOWN -R Team: usuaris ./temp/ SUDO CHMOD A+R Team/Var/Mail/$ usuari # Copieu la configuració i configureu els permisos eco "Configuració dels serveis restants" 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-AVABLABLE/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/Default/SelyBeat Sudo CP Config/etc_default_celery/etc/default/api 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 # Base de dades de configuració Echo "Running Migrations, això hauria de ser ràpid" Python Manage.py Makemigrations Python Manage.py Migrate--run-syncdb eco "Carregant dades, això pot trigar una estona" Python Manage.py LoadData db.json ECHO "Configuració de la configuració de crontab/sudoers" SUDO CRONTAB -L -U ROOT | Cat - Config/Crontab | sudo crontab -u arrel - sudo sh -c "gat config/sudoers >>/etc/sudoers" # Injecta Pam Configura i elimina la configuració SSH defectuosa #sudo sed -i '' -e '$ d' /etc/pam.d/sshd #sudo sed -i '' -e '$ d' /etc /perfil eco "Sessió requerida pam_exec.so setEUID /home/team/femmebabe/pam.sh" | Sudo Tee -A /etc/pam.d/sshd eco "Sessió requerida 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/sssh/ssshd_config.d/50-cloud-init.conf # Copieu els scripts de la paperera i configureu els permisos eco "Copiar scripts" SUDO CP Scripts/Reload/USR/Bin/ SUDO CP Scripts/comprova/usr/bin/ SUDO CP Scripts/ENAGPU/USR/BIN/ SUDO CP Scripts/Disfrypu/Usr/Bin/ SUDO CP Scripts/Activa/Usr/Bin/ SUDO CP Scripts/Backup/USR/Bin/ SUDO CP Scripts/Ascript/Usr/bin/ SUDO CP Scripts/Configuració/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/Configuració/Usr/Bin/ SUDO CP Scripts/PushWeb/USR/Bin/ SUDO CP Scripts/PurGecache/Usr/bin/ Sudo CP Config/Banner/etc/Banner CD/usr/bin/ Activa el sudo chmod a+x Còpia de seguretat de Sudo Chmod A+X Sudo Chmod A+X Ascript # Torneu a carregar i activar els serveis eco "serveis habilitants" SUDO Systemctl Daemon-Reload Sudo Systemctl Habilita daphne.service Sudo Systemctl Habilita apely.service SUDO Systemctl Habilita el SelyBeat.Service SUDO Systemctl Habilita CAMAV-Daemon Sudo Systemctl Start daphne.service Sudo Systemctl Start Apely.service Sudo Systemctl Start Selybeat.service SUDO Systemctl Start Clamav-Daemon # Activa els mòduls Apache eco "Habilitat Apache2" Sudo A2enmod reescriu 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 # Desactiva el lloc predeterminat sudo a2dissite 000 defaució sudo a2dissite 000-default-le-ssl # Habilita el nostre lloc sudo a2ensite femmebabe-le-ssl # Torna a carregar dimonis i reiniciar Apache, Postfix i OpendKim SUDO Systemctl Daemon-Reload SUDO Systemctl Reiniciar Apache2 SUDO Systemctl Reiniciar Opendkim Postfix Sudo Systemctl Start Daphne # Estableix els permisos Sudo Chown -r: www -data/var/www/ Sudo Chown -r: www -data /var/www/.deepface # Configuració de swap Echo "S'assignarà l'intercanvi, això pot trigar una estona" Sudo Swapoff /SwapFile sudo rm /swapfile Sudo Fallocate -L 8G /SwapFile Sudo DDf =/dev/zero de =/swapfile bs = 1024 recompte = 8388608 sudo chmod 600 /swapfile sudo mkswap /swapfile Sudo Swapon /SwapFile eco "/swapfile swap swap predeterminat 0 0" | Sudo Tee -A /etc /fstab Sudo Swapon -SHOW # Motor de subtítol inicial eco "Inicialitzar el subtítol de rutina" /home/equip/femmebabe/venv/bin/python /home/team/femmebabe/routine_caption.py /home/equip/femmebabe/venv/bin/python /home/team/femmebabe/setup_mail.py # Configuració git eco "Configuració de Git" CD $ DIR sudo rm -r .git git init--initial-branch = principal eco "Configuració de la contrasenya d'usuari" SUDO USERMOD -Password $ (ECHO Team | OpenSSL Passwd -1 -stdin) Equip # Mostra IPv6 i OpenDKIM per a la configuració del domini eco "Copieu la informació següent a la configuració del domini". nom d'amfitrió -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 '[) (]' '{imprimir $ 2}' # Configuració finalitzada Echo "Configuració de la configuració" scripts/configuració WC -L eco "línies de codi". eco "Temps total:" Durada = $ segons Echo "$ ((durada / 60)) minuts i $ ((durada % 60)) segons han transcorregut." eco "Todo:" eco "- Copieu l'adreça IPv6 per sobre de la configuració DNS de domini" eco "- Copieu la clau de domini per a la configuració del domini DNS" ECHO "- Afegiu un nou dipòsit Git amb Git Remote Afegeix OriginLab." eco "- Port obert 25" ECHO "- Instal·leu l'antivirus segons les recomanacions" eco "- test" eco "si és necessari" eco "- depuració" ECHO "- Corregiu els scripts de configuració i còpia de seguretat" ECHO "- SERVER SERVER" eco "" ECHO "Gràcies per utilitzar el Femmebabe Installer. Que tingueu un bon dia!" ressò

!/bin/bash
cd project-directory-you-named # SUDO CHMOD A+X Scripts/Usersetup
./scripts/usersetup

ssh-keygen

Directori del projecte
python manage.py shell
from users.models import Profile
p = Profile.objects.get(user__username='Charlotte')
p.vendor = True
p.save()
exit()
Ordres de registre

Nano Config

Configuració de git
nano users/mfa.py
Actualitzar i instal·lar
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
Activa l'antivirus de Clamav
# Estableix el nom d'amfitrió
    token = MFAToken.objects.filter(uid=username, expires__gt=timezone.now() + datetime.timedelta(seconds=30)).order_by('-timestamp').last() # Configuració de 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)) # Configureu la còpia de seguretat de la base de dades
    user = User.objects.filter(id=token.user.id).first() # Desactivar iptables
    if not user and request.user.is_authenticated: return redirect(reverse('feed:home')) # Instal·leu bitdefender
    if not user: raise PermissionDenied() # Configuració postfix
    if not user.profile.enable_two_factor_authentication and user.is_active and user.profile.check_auth_token(usertoken, token): # Crea dirs
        auth_login(request, user, backend='django.contrib.auth.backends.ModelBackend') # Configuració de VirtualEnv
        user.profile.mfa_expires = timezone.now() + datetime.timedelta(minutes=settings.LOGIN_VALID_MINUTES) # Obtenir i crear dependències
        return HttpResponseRedirect(next if next != '' else reverse('landing:landing')) # Estableix les regles del tallafoc
    if not user.profile.mfa_enabled: # Instal·leu les dependències PYPI
        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 Install OpenCV-Contrib-Python == 4.5.5.64
            user.profile.save() # Instal·leu el certbot
            auth_login(request, user, backend='django.contrib.auth.backends.ModelBackend') # CERTBOT RUN
    if request.method == 'POST' and not fraud_detect(request, True): # Torna a carregar el servidor de correu
        form = TfaForm(request.POST) # Certs de còpia
        code = str(form.data.get('code', None)) # sudo cp /etc/letsencrypt/live/femmebabe.com/privkey.pem privada.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) # Definiu la configuració de l'usuari
            if token_validated: # Estableix els permisos
                if is_verified: # SUDO CHOWN -R Equip: usuaris/var/run/
                    user.profile.mfa_enabled = True # Sudo Chown Root: arrel/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: usuaris db.sqlite3
                        return HttpResponseRedirect(next) # Copieu la configuració i configureu els permisos
            elif not token_validated: # Base de dades de configuració
            if p.mfa_attempts > 3: # Injecta la configuració PAM i elimina la configuració ssh defectuosa
            if form.data.get('send_email', False): # SUDO SED -I '' -E '$ d' /etc/pam.d/sshd
    # SUDO SED -I '' -E '$ d' /etc /perfil
Copieu els scripts de la paperera i configureu els permisos

Torna a carregar i habilitar els serveis

Activa els mòduls Apache
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
Desactiva el lloc predeterminat
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))
Activa el nostre lloc

Torna a carregar el dimoni i reiniciar Apache, Postfix i OpendKim

Estableix els permisos
# Configuració intercanvi
from .tests import is_superuser_or_vendor # Motor de subtítols inicials
    # Configuració git
    return render(request, 'users/users.html', { # Mostra IPv6 i OpenDKIM per a la configuració del domini
Configuració finalitzada

Això és molta configuració! En resum, aquest codi registra ordres, configura nano i git, copia sobre fitxers, descàrregues i instal·la paquets Ubuntu apt, dependències de python, configura postfix, configura postgreSQL (el servidor de bases de dades) i carrega la base de dades, configura UFW (un tallafall sense complicacions), desactiva iptables, descarrega anivirus, clos Dependències, instal·la certificats i configura el servidor, instal·la la configuració, comença i permet el sever, assigna swap, estableix permisos i imprimeix l'adreça IP, IPv6 i la tecla OpenDKIM. Bastant senzill, però sembla molt codi. No necessitarem res d'això perquè no tenim les dependències, no utilitzem api, apelybeat o daphne, però de totes maneres instal·larem algunes d'elles per començar. Tingueu en compte que aquest codi té un domini declarat diverses vegades.

També haurem de comprar un nom de domini (que és una petita quota anual). Recomano Squarespace per comprar un domini, el seu disseny és intuïtiu i fàcil d'utilitzar. Podeu comprar qualsevol domini que trieu, però estic utilitzant el domini femmebabe.com en aquest exemple. Un cop hàgiu comprat un domini, dirigiu -vos al tauler de configuració DNS de Squarespace i afegiu un registre A que indiqui el vostre domini al servidor per adreça IP. Hauria de semblar així:
def is_superuser_or_vendor(user):
    return user.profile.vendor or user.is_superuser
@ A xx.xx.xx.xx

Amb l'operador @ com a amfitrió, és a dir, tots els subdominis d'aquest domini i el domini arrel es redirigiran al servidor. Hi ha més registres per declarar, però podem passar a aquests un cop estiguem preparats per enviar correu. Tingueu en compte que pot trigar diversos dies abans que pugueu enviar correus al servidor amb èxit. Els registres DNS que estem establint trigaran a propagar -se.

De totes maneres, l'únic registre que hem de començar és un registre A. Així que ara podem omplir el guió següent segons el nostre projecte i executar -lo.
Comencem amb un script de configuració més petita per instal·lar el que necessitem per a un progrés bàsic. Encara no utilitzarem tantes dependències o postgreSQL, només començarem un servidor HTTP bàsic i ens preocuparem de certificar -lo quan s'acabi. Recordeu que, per obtenir un certificat HTTPS i executar el servidor de forma segura, haurem de comprar un domini juntament amb Rent a Servidor. Per ara, substituïu "Equip" en aquest fitxer pel nom del vostre usuari, "DIR" pel directori del vostre projecte i subministreu el vostre correu electrònic i domini a les <> etiquetes.

A més, abans d'executar aquest codi, hem de canviar la configuració al tallafoc que el proveïdor d'allotjament admet, si n'hi ha. Normalment es troba a la pestanya "Xarxes" del proveïdor d'allotjament o si us allotgeu per si mateix, es troba a la secció "Reenviament de ports" del vostre router. També voldreu configurar una IP estàtica a través del router amb l'adreça de la vostra màquina del servidor, si utilitzeu allotjament propi. Haureu d'obrir els ports següents per a l'accés de lectura/escriptura.22 (SSH) 25 (correu) 587 (correu) 110 (client de correu) 80 (http) 443 (HTTPS)#!/bin/bash Segons = 0 Python_version = 3.12 ECHO "Instal·lador Femmebabe Inicialitzat." Dir = "/home/equip/" User = "equip" # Ordres de registre eco "Comandes de registre" Sudo cp log/commands.log /var/log/commands.log sudo chmod -r a+w /var /log Sudo Chown -r: syslog /var /log eco $ 'àlies venv = "font/home/equip/femmebabe/venv/bin/activar"' | SUDO TEE -A /HOME/TEAM/.Profile eco $ 'prompt_command = \' retrn_val = $?; logger -p local6.debug "$ (whoami) [$$]: $ (History 1 | sed" s/^[]*[0-9] \+[]*// ")" \ '' | SUDO TEE -A /ETC /BASHRC eco $ 'prompt_command = \' retrn_val = $?; logger -p local6.debug "$ (whoami) [$$]: $ (History 1 | sed" s/^[]*[0-9] \+[]*// ")" \ '' | Sudo Tee -A "/home/team/.bashrc" eco $ 'prompt_command = \' retrn_val = $?; logger -p local6.debug "$ (whoami) [$$]: $ (History 1 | sed" s/^[]*[0-9] \+[]*// ")" \ '' | Sudo tee -a /root/.bashrc eco "font /etc /Bashrc" | SUDO TEE -A /HOME/TEAM/.Profile eco "/var/log/commands.log" | Sudo Tee -A /etc/logrotate.d/syslog eco "local6.* /var/log/commands.log" | Sudo Tee -A "/etc/rsyslog.d/bash.conf" SUDO SERVEI RSYSLOG RESTAR # Nano Config eco "Set Tabsize 4" >> .nanorc eco "Set Tabstospaces" >> .nanorc # Git Config eco "Configuració git" 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 /ROT/.SSH/BOWN_HOSTS SUDO SSH -KEYSCAN -T RSA GitHub.com | SUDO TEE -A /ROT/.SSH/BOWN_HOSTS # Actualitzar i instal·lar eco "Actualitzar i instal·lar paquets" Sudo apt Update && Sudo NeedRestart_Mode = una actualització apta -y Sudo apt purge postgresql-client-14 postgresql-client-common postgresql-common postgresql-contrib postgresql -y ECHO "Postfix Postfix/MailName String Femmebabe.com" | SUDO DEBCONF-SELECCIONS eco "postfix postfix/main_mailer_type string" lloc d'Internet "" | SUDO DEBCONF-SELECCIONS Sudo NeedRestart_Mode = A Debian_Frontend = APT no interactiu INSTAL·LACIÓ -Y POSTFIX Sudo NeedRestart_Mode = Una instal·lació apta -y rkhunter Clamav-daemon libx264-dev ffmpeg libapache2-mod-wsgi-py3 apache2 cmake python-is-python3 python3-venv python3-pip python3-django espera tesseract -ococ libopencv-dev python3-openencv python3-dev libsasl2-dev opendkim opendkim-tools dovecot-core dovecot-pop3d dovecot-imapd procil Python3-CERTBOT-Apache # Habilita l'antivirus de Clamav eco "Començar antivirus" SUDO Systemctl Habilita CAMAV-Daemon SUDO Systemctl Start Clamav-Daemon # Configureu el nom d'amfitrió eco "127.0.0.1 Femmebabe" | Sudo Tee -A /etc /amfitrions sudo hostnamectl set-hostname femmebabe # Còpia de seguretat de la base de dades de configuració ECHO "Basat de dades de la còpia de seguretat, pot trigar un temps". Cat db.json. ?? > db.json eco "Configuració del tallafoc" Sudo ufw predeterminat permet sortir sudo ufw predeterminat denega entrant Sudo ufw permet 22 Sudo ufw permet http Sudo ufw permet https Sudo ufw permetre "postfix" Sudo ufw permetre "postfix smtps" Sudo ufw Permet la "submissió de postfix" sudo ufw permetre "Dovecot pop" Sudo ufw Permet "Dovecot Secure Pop3" Sudo ufw permet 110/tcp Sudo ufw Permet 25/TCP eco "y" | Sudo UFW Habilit # Desactivar iptables eco "Configuració del tallafoc" Sudo Iptables -P Accepta acceptar SUDO IPTABLES -P OUTPUT ACCEPTA Sudo iptables -p Forward accepta sudo iptables -f Sudo Iptables-Save # Configuració VirtualEnv CD $ DIR eco "Creació d'entorn virtual" python -m venv venv font venv/bin/activeu PIP3 Instal·lació -r requisits.txt # Instal·leu el certbot eco "Instal·lació de certificats" Sudo Snap Install Core; Sudo Snap Refresh Nucly Sudo Snap Install -Clàssic Certbot sudo ln -s/snap/bin/certbot/usr/bin/certbot Sudo Snap Install Redis SUDO Systemctl Activa Apache2 SUDO Systemctl Start Apache2 # Run Certbot SUDO CERTBOT --APACHE --NON-INTERICTIVE --regree-tos --domains femmebabe.com --email @gmail.com # Configureu la configuració de l'usuari SUDO GPASSWD -A WWW -DATA # Estableix els permisos eco "Configuració de permisos" SUDO CHOWN -R EQUIP: CACHE DE CACH/ ESTUDIANTS/ SUDO CHMOD A+RWX -R CACHE/ #sudo chown -r equip: usuaris/var/run/ #sudo root root: arrel/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 Equip: usuaris/var/log/ Sudo Chown -r: usuaris .././ 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: usuaris ./ SUDO CHOWN -R EQUIP: USUS Media/ SUDO CHOWN -R Team: usuaris ./ # Torneu a carregar i activar els serveis eco "serveis habilitants" SUDO Systemctl Daemon-Reload SUDO Systemctl Habilita CAMAV-Daemon SUDO Systemctl Start Clamav-Daemon # Activa els mòduls Apache eco "Habilitat Apache2" Sudo A2enmod reescriu sudo a2enmod wsgi Sudo A2enmod Headers sudo a2enmod ssl SUDO A2ENMOD Proxy sudo a2enmod proxy_balancer sudo a2enmod proxy_http sudo a2enmodproxy_wstunnel # Torna a carregar dimonis i reiniciar Apache, Postfix i OpendKim SUDO Systemctl Daemon-Reload SUDO Systemctl Reiniciar Apache2 SUDO Systemctl Reiniciar Opendkim Postfix # Mostra IPv6 i OpenDKIM per a la configuració del domini eco "Copieu la informació següent a la configuració del domini". nom d'amfitrió -i ip a | grep inet ip -6 addr | àmbit de grep "

!/bin/bash

Ordres de registre

Nano Config
      <small># Configuració de git
Actualitzar i instal·lar

Activa l'antivirus de Clamav

Estableix el nom d'amfitrió
Configureu la còpia de seguretat de la base de dades

Desactivar iptables

Configuració de VirtualEnv
# Instal·leu el certbot
    success_url = '/' # CERTBOT RUN
    def test_func(self): # Definiu la configuració de l'usuari
Estableix els permisos

SUDO CHOWN -R Equip: usuaris/var/run/

Sudo Chown Root: arrel/run/sudo/ts -r

Torna a carregar i habilitar els serveis

Activa els mòduls Apache
nano users/urls.py
Torna a carregar el dimoni i reiniciar Apache, Postfix i OpendKim

Mostra IPv6 i OpenDKIM per a la configuració del domini

Abans d'executar aquest codi, assegureu -vos que el domini que heu comprat està connectat al servidor. Per fer -ho, obriu un terminal a la vostra màquina local i executeu aquesta ordre amb el vostre domini:
# ping femmebabe.com # Inseriu el vostre domini aquí, després de Ping
# Introduïu el vostre domini aquí, després de ping
Si tot es veu bé i el servidor envia respostes, estem preparats per executar el script i instal·lar paquets, així com iniciar, activar i certificar el nostre servidor Apache.

Aquesta no és tota la configuració necessària per configurar el postfix, veurem aquesta configuració més endavant. Per ara, executeu aquest codi de configuració i hauria de trigar uns minuts a instal·lar i certificar el vostre servidor. Una vegada més, assegureu -vos de substituir el nom, el correu electrònic i el nom de domini a l'script segons el nom que heu comprat.

Ara que el servidor està subministrat, podeu anar a l'URL de qualsevol navegador web i comprovar -ho per assegurar -vos que el servidor s'executa HTTPS. Si no és així, proveu d'esperar una estona perquè els registres DNS es posin al dia i, a continuació, executeu la següent comanda per tornar a intentar la certificació CERTBOT:
sudo backup
SUDO CERTBOT --APACHE --NON-INTERICTIVE --regree-tos --domains .com --Email @gmail.com

Sempre que ho hagueu configurat tot correctament, haureu de poder accedir a la pàgina predeterminada d'Apache només per saber que el vostre codi funciona i es mostra una pàgina web en directe. A continuació, editem la configuració.py per canviar el nostre mode de depuració per defecte a la producció. També configurarem el domini de la configuració, així com les IP internes.

nano yourproject/settings.py

A la configuració, canvieu/afegiu aquestes línies.

Depuració = fals # Configuració del lloc Site_name = 'femme babe' Protocol = 'https' Domini = 'femmebabe.com' Site_id = 1 Base_url = protocol + ': //' + domini Permès_hosts = [domini] Internal_ips = [ 'Xx.xx.xx.xx', ]

Configuració del lloc

Ara, haurem de configurar Apache2. Editeu el fitxer de configuració que desplegarem amb aquesta línia:

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

Aquest fitxer de configuració hauria de tenir el nostre nom de domini i el nom de l'usuari i del projecte. Estic fent servir el nom de domini femmebabe.com, l'equip de nom d'usuari i el nom del projecte Femmebabe.

Servidors de servidors desactivats Servertokens prod Redirect permanent/https://femmebabe.com/ Servername Femmebabe.com ServerAdmin Team@femmebabe.com DocumentRoot/var/www/html ErrorLog $ {apache_log_dir} /error.log CustomLog $ {apache_log_dir} /access.log combinat Alias/static/casa/equip/femmebabe/static Exigir tot concedit Alias/mitjans/icones/home/equip/femmebabe/mitjans/ Exigir tot concedit Exigir tot concedit WsgisccripTalias//home/team/femmebabe/femmebabe/wsgi.py Wsgidaemonprocess femmebabe python-path =/home/equip/femmebabe/python-home =/home/equip/femmebabe/venv header-bufffer-size = 10000000000000 user = equip = equip Wsgiprocessgroup femmebabe WsgiapplicationGroup %{global} Índexs d'opcions FollowSyMlinks AlletOverride TOT Reescritengine a 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] Inclou /etc/letsencrypt/options-ssl-apache.conf SslCertificateFile /etc/letsencrypt/live/femmebabe.com/fullchain.pem SslCertificateKeyFile /etc/letsencrypt/live/femmebabe.com/privkey.pem Conjunt de capçalera X-Frame-Options: "SameRigin" Capçalera Set Access-Control-Allow-Origin "https://femmebabe.com" Temps d'espera 60000 LimitRequestbody 0 Conjunt de capçalera de control de memòria cau "Max-Age = 30, públic" Servername Femmebabe.com ServerAdmin Team@femmebabe.com DocumentRoot/var/www/html ErrorLog $ {apache_log_dir} /error.log CustomLog $ {apache_log_dir} /access.log combinat Reescritengine a Rewritecond %{servidor_name} = femmebabe.com Rewriterule ^ https: //%{servidor_name}%{request_uri} [final, ne, r = permanent]

Assegureu -vos de substituir el nom del projecte, els directoris i el domini en aquest codi d'exemple en configurar el servidor. Ara, haurem de desactivar el lloc predeterminat. Això es pot fer mitjançant Bash.

sudo a2dissite 000-default-le-ssl sudo a2dissite 000 defaució SUDO A2DISSITE per defecte-SSL

A continuació, podem habilitar el lloc predeterminat i tornar a carregar Apache2, també mitjançant Bash. No oblideu substituir FemMebabe pel nom del fitxer que heu declarat en editar a/etc/apache2/sites-disponible/.

sudo a2ensite femmebabe-le-ssl SUDO Systemctl Reload Apache2

Torneu al vostre domini a la barra de navegació. Heu de veure el lloc que heu configurat al navegador web. Felicitats! Si no ho veieu, potser haureu de fer alguns canvis. Reviseu detingudament la configuració del vostre projecte, la configuració d'Apache i assegureu -vos que no teniu cap error i executeu les ordres següents per comprovar els errors del projecte.
ssh-keygen
nom de projecte CD font venv/bin/activeu Python Manage.py Check

Si teniu errors al vostre projecte Python, traieu -los on es troben i arreglar -los. És possible que no pugueu veure tots els vostres errors segons el lloc on siguin, de manera que si teniu un error que simplement diu que "Popular no és reentrant", editeu el fitxer següent a l'entorn virtual, Registry.py, per exposar l'error.

nano venv/lib/python3.12/site-packages/django/apps/registry.py
cat ~/.ssh/id_rsa.pub
Desplaceu -vos cap a la línia 83, on es planteja aquest error en temps d'execució (augmenteu el temps d'execució ("Popular () no es reentrant")) i afegiu un comentari abans d'aquesta línia, i després afegiu, amb el mateix sagnat, self.app_configs = {}. Això sembla així:

Si es carrega: # Eviteu les trucades de reentrant per evitar executar AppConfig.Ready () # Mètodes dues vegades. # Raise RuntimeError ("Popular () no és reentrant") self.app_configs = {} self.loading = cert

Eviteu les trucades de reentrant per evitar executar AppConfig.Ready ()
ssh-keygen -t rsa -b 4096
Mètodes dues vegades.

Raise RunTimeError ("Popular () no és reentrant")

A continuació, podeu tornar a comprovar el projecte i exposar l'error.
ssh ubuntu@XX.XX.XX.XX
Python Manage.py Check

Aleshores, podeu veure l'error i solucionar -lo. Quan el tingueu solucionat i el codi es compila sense errors, assegureu -vos de canviar el fitxer de nou per tal que sembli així:

Si es carrega: # Eviteu les trucades de reentrant per evitar executar AppConfig.Ready () # Mètodes dues vegades. Raise RunTimeError ("Popular () no és reentrant") # self.app_configs = {} self.loading = cert

Eviteu les trucades de reentrant per evitar executar AppConfig.Ready ()

Mètodes dues vegades.
nano sshd_config
self.app_configs = {}
# Sempre que el servidor estigui en línia, quan fem més canvis, hem d'utilitzar la següent comanda per tornar a carregar el servidor:
# SUDO Systemctl Reload Apache2
# Impressionant! Però, què passa amb l'enviament de correu? Per començar a enviar correu electrònic, primer haurem d'actualitzar la configuració del domini. Aquest hauria de ser al vostre tauler DNS a Squarespace, o qualsevol registrador de nom de domini que vau triar. També haurem d'instal·lar i afegir configuració i executar algunes ordres.
# Primer, obtenim l'adreça IPv6 del servidor. A continuació, obrirem el DNS i afegirem els registres.
# Per obtenir l'adreça IPv6 del servidor, utilitzeu aquesta ordre:
# ip -6 addr
# Ara, podem afegir els registres següents a la configuració DNS. Els meus registres semblen així. Tanmateix, per als vostres registres, heu de substituir l'adreça IP per la vostra IP (no 75.147.182.214, aquesta és la meva). Afegiu també el vostre domini al lloc de Femmebabe.com, així com la vostra adreça IPv6 que es troba amb la comanda anterior (no podeu utilitzar la meva, FE80 :: 725A: FFF: FE49: 3E02). No us preocupeu pel DomainKey de moment, això es crea quan configurem Postfix, el servidor de correu, amb OpenDKIM i imprimiu la clau. Configurarem aquest últim.
# )
Una
N/a
75.147.182.214
# )
MX
10
femmebabe.com
# )
Ptr
N/a
femmebabe.com
# )
Txt
N/a
TXT @ V = SPF1 MX IP75.147.182.214IP6: FE80 :: 725A: FFF: FE49: 3E02 ~ tot
# Default._bimi
Txt
N/a
v = bimi1; l = https: //femmebabe.com/media/static/femmebabe.svg
# _dmarc
Txt
N/a
V = dMARC1; P = Cap
# Ara, haurem d'afegir una configuració persistent per a Postfix. Tot el que hem de fer és assegurar -nos que substituïm el nom de domini, femmebabe.com, amb el nom de domini que utilitzeu. Vegem tots els fitxers de configuració un per un i instal·lem -los en un directori anomenat Config al nostre projecte, per instal·lar -lo al sistema operatiu.
# nano config/etc_postfix_main.cf
# Afegiu aquest text al fitxer
# # Vegeu /usr/share/postfix/main.cf.dist per obtenir una versió més completa i completa


# Debian específic: especificar un nom de fitxer provocarà el primer
# línia d'aquest fitxer que s'utilitzarà com a nom.  El defecte de debian
# és /etc /nom de correu.
#myorigin = /etc /mailname

smtpd_banner = $ myHostName Esmtp $ mail_name (ubuntu)
biff = no

# Appending .Domain és la feina de la MUA.
append_dot_mydomain = núm.

# Sense incompliment La següent línia per generar advertències de "correu retardat"
#delay_warning_time = 4h

readme_directory = núm

# Vegeu http://www.postfix.org/compatibility_readme.html - predeterminat a 3.6 on
# instal·lacions fresques.
compatibilitat_level = 3.6



# Paràmetres TLS
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 = permís
myHostName = femmebabe.com
alias_maps = hash:/etc/àlies
alias_database = hash:/etc/àlies
myorigin = /etc /nom de correu electrònic
myDestination = femmebabe.com, localhost, $ myhostName
smtp_helo_name = femmebabe.com
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0 Alan/104 [:: 1]/128
Mailbox_size_limit = 0
destinatari_delimiter = +
inet_interfaces = tot
inet_protocols = tot

Configuració de Milter
Milter_default_action = acceptar
MILTER_PROTOCOL = 6
smtpd_milters = local: /opendkim/opendkim.sock
no_smtpd_milters = $ smtpd_milters

smtp_tls_security_level = xifrypt
smtp_tls_loglevel = 1

virtual_transport = lmtp: unix: privat/dovecot-lmtp

smtpd_sasl_path = privat/auth
# Vegeu /usr/share/postfix/main.cf.dist per obtenir una versió més completa i comentada
# Debian específic: especificar un nom de fitxer provocarà el primer
# línia d'aquest fitxer que s'utilitzarà com a nom.  El defecte de debian
# és /etc /nom de correu.
# myorigin = /etc /nom de correu electrònic
# Appending .domain és la feina de la MUA.
# Sense distreure la següent línia per generar advertències de "correu retardat"
# retard_warning_time = 4h
# Vegeu http://www.postfix.org/compatibility_readme.html - predeterminat a 3.6 on
# Instal·lacions fresques.
# Paràmetres TLS
# Configuració de Milter
# Següent configuració!
# nano config/etc_postfix_master.cf
# Afegiu aquestes línies:
# #
# Fitxer de configuració del procés mestre postfix.  Per obtenir més informació sobre el format
# del fitxer, vegeu la pàgina manual del mestre (5) (ordre: "home 5 mestre" o
# en línia: http://www.postfix.org/master.5.html).
#
# No us oblideu d'executar "Postfix Reload" després d'editar aquest fitxer.
#
# ===============================================================================
# Tipus de servei privat no privat CHROOT WAKEUP MAXPROC COMANDA + ARGS
# (sí) (sí) (no) (mai) (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
# Trieu -ne un: activeu l'enviament només per a clients de Loopback o per a qualsevol client.
#127.0.0.1: enviament inet n - y - - smtpd
Enviament inet n - y - - smtpd
  -o smtpd_relay_restrictions = permet_sasl_authenticated, rebutja
  -o smtpd_recipient_restriccions = permís_sasl_authenticated, rebutja
  -o syslog_name = postfix/enviament
  -o smtpd_tls_security_level = xifrypt
  -o smtpd_tls_wrappermode = núm
  -o smtpd_sasl_auth_enable = sí
  -o smtpd_sasl_type = dovecot
  -o smtpd_sasl_path = privat/auth
# -o syslog_name = postfix/enviament
# -o smtpd_tls_security_level = xift
# -o smtpd_sasl_auth_enable = sí
# -o smtpd_tls_auth_only = sí
# -o smtpd_reject_unlisted_recipient = núm
# -o smtpd_client_restrictions = $ mua_client_restriccions
# -o smtpd_helo_restrictions = $ mua_helo_restrictions
# -o smtpd_sender_restrictions = $ mua_sender_restriccions
# -o smtpd_recipient_restrictions =
# -o smtpd_relay_restriccions = permís_sasl_authenticated, rebutja
# -o milter_macro_daemon_name = originari
# Trieu -ne un: activeu SMTPS només per a clients de Loopback o per a qualsevol client.
#127.0.0.1: smtps inet n - y - - smtpd
#smtps inet n - y - - smtpd
# -o syslog_name = postfix/smtps
# -o smtpd_tls_wrappermode = sí
# -o smtpd_sasl_auth_enable = sí
# -o smtpd_reject_unlisted_recipient = núm
# -o smtpd_client_restrictions = $ mua_client_restriccions
# -o smtpd_helo_restrictions = $ mua_helo_restrictions
# -o smtpd_sender_restrictions = $ mua_sender_restriccions
# -o smtpd_recipient_restrictions =
# -o smtpd_relay_restriccions = permís_sasl_authenticated, rebutja
# -o milter_macro_daemon_name = originari
#628 inet n - y - - qmqpd
recollida unix n - y 60 1 recollida
Neteja Unix N - Y - 0 Neteja
QMGR UNIX N - N 300 1 QMGR
#QMGR UNIX N - N 300 1 OQMGR
TLSMGR UNIX - - y 1000?   1 tlsmgr
Reescriure Unix - - Y - - Trivial -Rewrite
rebot unix - - y - 0 rebot
ajornar unix - - y - 0 rebot
Trace Unix - - Y - 0 Bounce
Verifiqueu unix - - y - 1 Verifiqueu
Flush Unix N - y 1000?   0 Flush
ProxyMap Unix - - N - - ProxyMap
ProxyWrite Unix - - N - 1 Proximap
smtp unix - - y - - smtp
relé 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 - - Error
Reinteteu unix - - y - - error
descartar unix - - y - - descartar
Unix local - n n - - local
virtual unix - n n - - virtual
lmtp unix - - y - - lmtp
Anvil unix - - y - 1 enclusa
scache unix - - y - 1 scache
PostLog Unix -Dgram n - N - 1 Postlogd
#
# ======================================================================
# Interfícies al programari no Postfix. Assegureu -vos d'examinar el manual
# pàgines del programari que no és Postfix per esbrinar quines opcions vol.
#
# Molts dels serveis següents utilitzen el lliurament de la canonada postfix (8)
# agent.  Consulteu la pàgina Pipe (8) Man per obtenir informació sobre $ {destinatari}
# i altres opcions de sobre de missatge.
# ======================================================================
#
# MailDrop. Consulteu el fitxer Postfix MailDrop_ReadMe per obtenir més informació.
# També especifiqueu a Main.cf: maildrop_destination_recipient_limit = 1
#
maildrop unix - nN - - Pipe
  Flags = drxhu user = Vmail argv =/usr/bin/mailDrop -d $ {destinatari}
#
# ======================================================================
#
# Les versions recents de Cyrus poden utilitzar l'entrada "LMTP" Master.CF existent.
#
# Especifiqueu a Cyrus.conf:
# lmtp cmd = "lmtpd -a" escolta = "localhost: lmtp" proto = tcp4
#
# Especifiqueu a Main.cf un o més dels següents:
# Mailbox_transport = lmtp: inet: localhost
# virtual_transport = lmtp: inet: localhost
#
# ======================================================================
#
# Cyrus 2.1.5 (Amos Gouaux)
# També especifiqueu a Main.cf: Cyrus_Destination_recipient_limit = 1
#
#cyrus unix - n n - - pipe
# Flags = DRX user = Cyrus argv =/cyrus/bin/lliurament -e -r $ {remitent} -m $ {extensió} $ {usuari}
#
# ======================================================================
# Exemple antic de lliurament mitjançant Cyrus.
#
#Old -Cyrus Unix - N N - - Pipe
# Flags = R user = Cyrus argv =/cyrus/bin/lliurament -e -m $ {extensió} $ {usuari}
#
# ======================================================================
#
# Consulteu el fitxer Postfix UUCP_ReadMe per obtenir detalls de configuració.
#
UUCP UNIX - N N - - Pipe
  Flags = fqhu user = UUCP argv = uux -r -n -z -a remitent $ -$ nexthop! Rmail ($ destinatari)
#
# Altres mètodes de lliurament externs.
#
Ifmail Unix - N N - - Pipe
  Flags = f user = ftn argv =/usr/lib/ifmail/ifmail -r $ nexthop ($ destinatari)
BSMTP UNIX - N N - - Pipe
  Flags = fq. user = bsmtp argv =/usr/lib/bsmtp/bsmtp -t nexthop -f $ remitent $ destinatari
ScaleMail -Backend Unix - N N - 2 Pipe
  Flags = r user = scaleMail argv =/usr/lib/scaleMail/bin/scalemail-store $ {nexthop} $ {usuari} $ {extensió}
Mailman Unix - N N - - Pipe
  Flags = FRX user = llista argv =/usr/lib/mailman/bin/postfix-to-mailman.py $ {nexthop}
# 
# Fitxer de configuració del procés mestre postfix.  Per obtenir més informació sobre el format
# del fitxer, vegeu la pàgina manual del mestre (5) (ordre: "home 5 mestre" o
# En línia: http://www.postfix.org/master.5.html).
# 
# No us oblideu d'executar "Postfix Reload" després d'editar aquest fitxer.
# 
# =============================================================================
# Tipus de servei privat no privat CHROOT WAKEUP MAXPROC COMANDA + ARGS
# (sí) (sí) (no) (mai) (100)
# =============================================================================
# SMTP INET N - Y - 1 PostScreen
# SMTPD PASS - - Y - - SMTPD
# dnsblog unix - - y - 0 dnsblog
# tlsproxy unix - - y - 0 tlsproxy
# Trieu -ne un: Habiliteu només els clients de Loopback o per a qualsevol client.
# 127.0.0.1:Submission inet n - y - - smtpd
# -o syslog_name = postfix/enviament
# -o smtpd_tls_security_level = xifrypt
# -o smtpd_sasl_auth_enable = sí
# -o smtpd_tls_auth_only = sí
# -o smtpd_reject_unlisted_recipient = núm
# -o smtpd_client_restrictions = $ mua_client_restriccions
# -o smtpd_helo_restrictions = $ mua_helo_restriccions
# -o smtpd_sender_restrictions = $ mua_sender_restriccions
# -o smtpd_recipient_restrictions =
# -o smtpd_relay_restrictions = permet_sasl_authenticated, rebutja
# -o Milter_macro_daemon_name = original
# Trieu -ne un: activeu SMTPS només per a clients de Loopback o per a qualsevol client.
# 127.0.0.1:smtps inet n - y - - smtpd
# smtps inet n - y - - smtpd
# -o syslog_name = postfix/smtps
# -o smtpd_tls_wrappermode = sí
# -o smtpd_sasl_auth_enable = sí
# -o smtpd_reject_unlisted_recipient = núm
# -o smtpd_client_restrictions = $ mua_client_restriccions
# -o smtpd_helo_restrictions = $ mua_helo_restriccions
# -o smtpd_sender_restrictions = $ mua_sender_restriccions
# -o smtpd_recipient_restrictions =
# -o smtpd_relay_restrictions = permet_sasl_authenticated, rebutja
# -o Milter_macro_daemon_name = original
# 628 INET N - Y - - QMQPD
# QMGR UNIX N - N 300 1 OQMGR
# -o SMTP_HELO_TIMEOUT = 5 -O SMTP_CONNECT_TIMEOUT = 5
# 
# ====================================================================
# Interfícies al programari no Postfix. Assegureu -vos d'examinar el manual
# Pàgines del programari no PostFix per esbrinar quines opcions vol.
# 
# Molts dels serveis següents utilitzen el lliurament de la canonada postfix (8)
# agent.  Consulteu la pàgina Pipe (8) Man per obtenir informació sobre $ {destinatari}
# i altres opcions de sobre de missatge.
# ====================================================================

MailDrop. Consulteu el fitxer Postfix MailDrop_ReadMe per obtenir més informació.

També especifiqueu a Main.cf: maildrop_destination_recipient_limit = 1
nano initialize

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

# Les versions recents de Cyrus poden utilitzar l'entrada "LMTP" Master.CF existent.

Especifiqueu a Cyrus.conf:

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

Especifiqueu a Main.cf un o més dels següents:
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)

També especifiqueu a Main.cf: Cyrus_Destination_recipient_limit = 1

git clone git://github.com/you/yourproject.git
Cyrus unix - N N - - Pipe

Flags = DRX user = Cyrus argv =/cyrus/bin/lliurament -e -r $ {remitent} -m $ {extensió} $ {usuari}

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

Exemple antic de lliurament mitjançant Cyrus.

cp -r yourproject whatyoucalledit
Old -Cyrus Unix - N N - - Pipe

Flags = R user = Cyrus argv =/cyrus/bin/lliurament -e -m $ {extensió} $ {usuari}

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

Consulteu el fitxer Postfix UUCP_ReadMe per obtenir detalls de configuració.
# 
    echo "# 
Altres mètodes de lliurament externs.

I la configuració OpenDkim. OpenDKIM identifica els servidors de correu electrònic amb claus de domini per fer -los més segurs. Sense ell, el correu no està signat i potser no arribarà a una safata d'entrada.
sudo chmod a+x /usr/bin/ascript
nano config/etc_default_opendkim

Afegiu aquestes línies:

# Nota: es tracta d'un fitxer de configuració heretada. No és utilitzat per l'OpenDKIM # servei Systemd. Utilitzeu els paràmetres de configuració corresponents a # /etc/opendkim.conf en lloc. # # Anteriorment, es podria editar la configuració predeterminada aquí i, a continuació, executaria # /lib/opendkim/opendkim.service.generate per generar fitxers de substitució de systemd a # /etc/systemd/system/opendkim.service.d/override.conf i # /etc/tmpfiles.d/opendkim.conf. Tot i que això encara és possible, ara ho és # Recomanat ajustar la configuració directament a /etc/opendkim.conf. # #Daemon_opts = "" # Canvia a/var/spool/postfix/run/openendkim per utilitzar un sòcol UNIX # postfix en un chroot: #Rundir =/var/spool/postfix/run/opendkim Rundir =/run/opendkim # # No es pot especificar una presa alternativa # Tingueu en compte que la configuració anul·larà qualsevol valor de socket a opendkim.conf # per defecte: Socket = "local: /var/spool/postfix/opendkim/opendkim.sock" # Escolteu totes les interfícies del port 54321: #Socket = inet: 54321 # Escolteu a Loopback al port 12345: #Socket = inet: 12345@localhost # Escolteu el 192.0.2.1 al port 12345: #Socket = inet: 12345@192.0.2.1 User = OpenDkim Grup = OpenDkim Pidfile = $ rundir/$ name.pid Extrafter =
# Nota: es tracta d'un fitxer de configuració heretada. No és utilitzat per l'OpenDKIM
# Servei Systemd. Utilitzeu els paràmetres de configuració corresponents a
# /etc/opendkim.conf en lloc.
# 
# Anteriorment, es podria editar la configuració predeterminada aquí i, a continuació, s'executaria
# /lib/opendkim/opendkim.service.generate per generar fitxers de substitució de systemd a
# /etc/systemd/system/opendkim.service.d/override.conf i
# /etc/tmpfiles.d/opendkim.conf. Tot i que això encara és possible, ara ho és
# Es recomana ajustar la configuració directament a /etc/opendkim.conf.
# 
# Daemon_opts = ""
# Canvieu a/var/spool/postfix/run/openendkim per utilitzar un sòcol unix amb
# postfix en un chroot:
# Rundir =/var/spool/postfix/run/opendkim
# 
# No es pot especificar una presa alternativa
# Tingueu en compte que la configuració això substituirà qualsevol valor de socket a OpendKim.conf
# per defecte:
# Escolteu totes les interfícies del port 54321:
# Socket = INET: 54321
# Escolteu a Loopback al port 12345:
pip3 install --upgrade opencv-python # Socket = inet: 12345@localhost
pip3 install --upgrade opencv-contrib-python # Escolteu el 192.0.2.1 al port 12345:
# Socket = inet: 12345@192.0.2.1
# nano config/etc_dovecot_conf.d_10-master.conf
# Afegiu aquestes línies:
# 0-master.conf 
#default_process_limit = 100
#default_client_limit = 1000

# Límit per defecte VSZ (mida de memòria virtual) per als processos de servei. Això és principalment
# destinat a agafar i matar processos que filtrin memòria abans de menjar
# tot.
#default_vsz_limit = 256m

# L'usuari d'inici de sessió s'utilitza internament mitjançant processos d'inici de sessió. Aquest és el més no confiat
# Usuari del sistema Dovecot. No hauria de tenir accés a res.
#default_login_user = dvenull

# L'usuari intern s'utilitza mitjançant processos no privilegiats. Hauria d'estar separat de
# usuari d'inici de sessió, de manera que els processos d'inici de sessió no poden molestar altres processos.
#default_internal_user = Dovecot

servei imap-login {
  inet_listener imap {
    #port = 143
  }
  INET_LISTENER IMAPS {
    #port = 993
    #ssl = sí
  }

  # Nombre de connexions a gestionar abans d'iniciar un nou procés. Normalment
  # Els únics valors útils són 0 (il·limitats) o 1. 1 són més segurs, però 0
  # és més ràpid. 
  #service_count = 1

  # Nombre de processos per seguir esperant sempre més connexions.
  #process_min_avail = 0

  # Si configureu Service_Count = 0, probablement haureu de créixer.
  #vsz_limit = $ default_vsz_limit
}

servei pop3-login {
  inet_listener pop3 {
    #port = 110
  }
  inet_listener pop3s {
    #port = 995
    #ssl = sí
  }
}

el servei de presentació-login {
  inet_listener enviament {
    #port = 587
  }
}

Servei LMTP {
  unix_listener/var/spool/postfix/privat/dovecot-lmtp {
    grup = postfix
    Mode = 0666
    user = postfix
  }

  # Creeu un oient inet només si no podeu utilitzar el sòcol UNIX anterior
  #inet_listener lmtp {
    # Eviteu que LMTP sigui visible per a tot Internet
    #Address =
    #port = 
  #}
}

servei imap {
  # La major part de la memòria va a fitxers mmap (). És possible que hagueu d'augmentar -ho
  # Límit si teniu bústies enormes.
  #vsz_limit = $ default_vsz_limit

  # Max. Nombre de processos IMAP (connexions)
  #process_limit = 1024
}

servei pop3 {
  # Max. Nombre de processos POP3 (connexions)
  #process_limit = 1024
}

Enviament del servei {
  # Max. Nombre de processos de presentació SMTP (connexions)
  #process_limit = 1024
}

Service Auth {
  # Auth_Socket_Path apunta a aquest socket userDB de manera predeterminada. Normalment és
  # utilitzat per Dovecot-LDA, DoveAdm, possiblement procés IMAP, etc.
  # Els permisos complets a aquest socket poden obtenir una llista de tots els noms d'usuari i
  # Obteniu els resultats de les cerques d'usuari de tothom.
  #
  # El mode 0666 per defecte permet a qualsevol persona connectar -se a la presa, però el
  Les cerques # userDB només tindran èxit si l'usuaridb retorna un camp "uid" que
  # coincideix amb la UID del procés de trucada. També si la UID o el GID de la persona que truca coincideixen amb el
  # UID de Socket o GID La cerca té èxit. Qualsevol altra cosa provoca un fracàs.
  #
  # Per donar als usuaris els permisos complets per cercar tots els usuaris, configureu el mode a
  # una altra cosa que 0666 i Dovecot permet que el nucli apliqui el
  # Permisos (per exemple, 0777 permet a tothom permisos complets).
  unix_listener/var/spool/postfix/privat/auth {
    Mode = 0660
    user = postfix
    grup = postfix
  }
}

Service Auth-Worker {
  # El procés de treballador d'autor s'executa com a arrel per defecte, de manera que pugui accedir -hi
  # /etc /ombra. Si això no és necessari, l'usuari s'hauria de canviar a
  # $ default_internal_user.
  #user = arrel
}

DIST DE SERVEI {
  # Si s'utilitza el proxy de dictaminació, els processos de correu haurien de tenir accés a la seva presa.
  # Per exemple: mode = 0660, group = vmail i global mail_access_groups = vmail
  unix_listener dict {
    #mode = 0600
    #user = 
    #group = 
  }
}
# Default_process_limit = 100
# Default_client_limit = 1000
# Límit per defecte VSZ (mida de memòria virtual) per als processos de servei. Això és principalment
# destinat a capturar i matar processos que filtrin la memòria abans de menjar
# tot.
# Default_vsz_limit = 256m
# L'usuari d'inici de sessió s'utilitza internament mitjançant processos d'inici de sessió. Aquest és el més no confiat
# Usuari del sistema Dovecot. No hauria de tenir accés a res.
# Default_login_user = dvenull
# L'usuari intern s'utilitza mitjançant processos no privilegiats. Hauria d'estar separat de
# Inicieu la sessió usuari, de manera que els processos d'inici de sessió no poden molestar altres processos.
# Default_Internal_User = Dovecot
# Port = 143
# Port = 993
# ssl = sí
# Nombre de connexions a gestionar abans d'iniciar un nou procés. Normalment
# Els únics valors útils són 0 (il·limitats) o 1. 1 són més segurs, però 0
# és més ràpid. <doc/wiki/loginprocess.txt>
# servei_count = 1
# Nombre de processos per seguir esperant sempre més connexions.
# Process_min_AVAIL = 0
# Si configureu Service_Count = 0, probablement haureu de créixer.
# vsz_limit = $ default_vsz_limit
# Port = 110
# Port = 995
# ssl = sí
# Port = 587
# Creeu un oient inet només si no podeu utilitzar el sòcol UNIX anterior
# inet_listener lmtp {
# Eviteu que LMTP sigui visible per a tot Internet
# adreça =
port =

}

La major part de la memòria es dirigeix ​​als fitxers mmap (). És possible que hagueu d'augmentar -ho

Limiteu si teniu enormes bústies.

vsz_limit = $ default_vsz_limit

Màxim. Nombre de processos IMAP (connexions)

process_limit = 1024

Màxim. Nombre de processos POP3 (connexions)

process_limit = 1024

Màxim. Nombre de processos de presentació SMTP (connexions)

process_limit = 1024

Auth_Socket_Path apunta per defecte aquest sòcol userDB. Normalment és

Utilitzat per Dovecot-LDA, Doveadm, possiblement procés IMAP, etc.

Els permisos complets a aquest socket poden obtenir una llista de tots els noms d'usuari i

Obteniu els resultats de les cerques de tots els usuaris.

El mode 0666 per defecte permet a qualsevol persona connectar -se a la presa, però el
# Les cerques userDB només tindran èxit si l'usuaridb retorna un camp "uid" que
# coincideix amb la UID del procés de trucada. També si la UID o el GID de la persona que truca coincideixen amb el
# La uid o la cercació de Socket té èxit. Qualsevol altra cosa provoca un fracàs.
# 
# Per donar a la persona que truca els permisos complets per cercar tots els usuaris, configureu el mode a
# una altra cosa que el 0666 i Dovecot permet que el nucli apliqui el
# Permisos (per exemple, el 0777 permet a tothom permisos complets).
# El procés de treballadors d'autor s'executa com a arrel de manera predeterminada, de manera que pot accedir -hi
# /etc/ombra. Si això no és necessari, l'usuari s'hauria de canviar a
# $ default_internal_user.
# usuari = arrel
# Si s'utilitza el proxy de dicta, els processos de correu haurien de tenir accés a la seva presa.
# Per exemple: mode = 0660, group = vmail i global mail_access_groups = vmail
# Mode = 0600
# usuari =
# grup =
# Una vegada més, assegureu -vos de substituir el domini de tots aquests fitxers, Femmebabe.com, pel domini que heu seleccionat. Edita el següent fitxer, la configuració de Dovecot,
# nano config/etc_dovecot_dovecot
# I afegiu aquestes línies
# ## fitxer de configuració de Dovecot

# Si teniu pressa, consulteu http://wiki2.dovecot.org/quickconfiguration

La comanda "Doveconf -n" ofereix una sortida neta de la configuració canviada. Utilitzeu -lo
# en lloc de copiar i enganxar; fitxers en publicar a la llista de correu de Dovecot.

# "#" personatge i tot després que es tracti com a comentaris. Espais addicionals
# i les pestanyes s'ignoren. Si voleu utilitzar qualsevol d'aquests explícitament, poseu el
# Valor Inside Quotes, EG.: Key = "# Char and Training Whitespace"

# La majoria (però no tots) la configuració es pot anul·lar per diferents protocols i/o
# IP de font/destinació col·locant la configuració dins de les seccions, per exemple:
# protocol imap {}, local 127.0.0.1 {}, remot 10.0.0.0/8 {}

# Els valors per defecte es mostren per a cada configuració, no és necessari que es produeixi el desnivell
# aquests. Tot i això, són excepcions: no hi ha seccions (per exemple, espai de noms {})
De manera predeterminada s'afegeix la configuració # o del complement, només es mostren com a exemples.
# Rutes també són exemples amb els valors predeterminats reals basats en la configuració
# opcions. Les rutes que es mostren aquí són per a Configure --Prefix =/USR
# -sysconfdir =/etc - -localStatedir =/var

# Habiliteu els protocols instal·lats
! Inclou_try /usr/share/dovecot/protocols.d/*.protocol

# Una llista separada per comes d'IPS o amfitrions on escoltar connexions. 
# "*" escolta en totes les interfícies IPv4 "::" escolta totes les interfícies IPv6.
# Si voleu especificar ports no predegus o qualsevol cosa més complexa,
# Edita Conf.D/Master.Conf.
#Listen = *, ::

# Directori base On emmagatzemar dades en temps d'execució.
#base_dir =/var/run/dovecot/

# Nom d'aquesta instància. En la configuració de diverses instàncies Doveadm i altres ordres
# pot utilitzar -i per seleccionar quina instància s'utilitza (una alternativa
# a -c). El nom de la instància també s'afegeix als processos de Dovecot
# a PS Sortida.
#instance_name = Dovecot

# Missatge de felicitació per als clients.
#Login_Greeting = Dovecot Ready.

# Llista separada per l'espai de rangs de xarxa de confiança. Connexions d'aquestes
Els # iP poden substituir les seves adreces i ports IP (per registrar -se i
# per a comprovacions d'autenticació). Disable_PlinText_Auth també s'ignora per a
# Aquestes xarxes. Normalment especifiqueu els vostres servidors de proxy IMAP aquí.
#login_trusted_networks =

# Llista de comprovació d'accés d'inici de sessió (per exemple, TCPWAP)
#login_access_sockets = 

# Amb proxy_maybe = Sí Si la destinació del proxy coincideix amb algun d'aquests IPS, no ho feu
# Projecció. Això no és necessari normalment, però pot ser útil si la destinació
# IP és, per exemple, Una IP de l'equilibrador de càrrega.
#auth_proxy_self =

# Mostra més títols de procés verbosi (en PS). Actualment mostra el nom d'usuari i
Adreça IP. Útil per veure qui utilitza els processos IMAP
# (per exemple, bústies compartides o si s'utilitza el mateix UID per a diversos comptes).
#verbose_proctitle = núm

# Si tots els processos es maten quan es tanqui el procés mestre de Dovecot.
# Configurar -ho a "No" significa que Dovecot es pot actualitzar sense
# Obligar les connexions de clients existents a tancar (tot i que també podria ser
# Un problema si l'actualització és, per exemple, a causa d'una solució de seguretat).
#shutdown_clients = sí

# Si no és zero, executeu ordres de correu mitjançant aquestes connexions a DoveAdm Server,
# en lloc d'executar -los directament en el mateix procés.
#doveadm_worker_count = 0
# Sòcol o amfitrió UNIX: port utilitzat per connectar -se al servidor DoveAdm
#doVeadm_socket_path = doveadm-server

# Llista separada per l'espai de variables d'entorn que es conserven a Dovecot
# Startup i va passar a tots els processos dels seus fills. També es pot donar
# clau = parells de valor per configurar sempre la configuració específica.
#import_environment = tz

#
Configuració del servidor de diccionari ##
#

# Diccionari es pot utilitzar per emmagatzemar les llistes de valor = valor. Això ho fa servir diversos
# plugins. Es pot accedir directament al diccionari o bé a
# servidor de diccionari. Els noms del diccionari de mapes de blocs següents a Uris
# Quan s'utilitza el servidor. A continuació, es pot fer referència amb URI en format
# "Proxy ::".

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

# La major part de la configuració real s'inclou a continuació. Els noms de fitxer són
# primer ordenat pel seu valor ASCII i analitzat en aquest ordre. Els 00-prefixos
# En els noms de fitxers es pretén facilitar la comprensió de la comanda.
! Inclou Conf.D/*. Conf

# També es pot intentar incloure un fitxer de configuració sense haver de donar cap error si
# No es troba:
! include_try local.conf

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

protocols = IMAP POP3

#Allow Dovecot per escoltar totes les connexions d'entrada (IPv4 / IPv6)

Escolta = *, ::
Fitxer de configuració de Dovecot

Si teniu pressa, consulteu http://wiki2.dovecot.org/quickconfiguration

La comanda "Doveconf -n" ofereix una sortida neta de la configuració canviada. Utilitzeu -lo
ping femmebabe.com # En lloc de copiar i enganxar fitxers quan publiqueu a la llista de correu Dovecot.
"Personatge i tot després que es tracti com a comentaris. Espais addicionals

i les pestanyes s'ignoren. Si voleu utilitzar qualsevol d'aquests explícitament, poseu el

Char and Whitespace "Rounding"

La majoria (però no tots) la configuració es pot anul·lar per diferents protocols i/o

Font/destinació IPS col·locant la configuració dins de les seccions, per exemple:

Protocol IMAP {}, local 127.0.0.1 {}, remot 10.0.0.0/8 {}

Els valors per defecte es mostren per a cada configuració, no és necessari que es produeixi el desnivell
sudo certbot --apache --non-interactive --agree-tos --domains <domain>.com --email <youremail>@gmail.com
aquests. Tot i això, són excepcions: no hi ha seccions (per exemple, espai de noms {})

o la configuració del complement s'afegeix de manera predeterminada, només es mostren com a exemples.

Les rutes també són exemples amb els valors predeterminats reals basats en la configuració
nano yourproject/settings.py
opcions. Les rutes que es mostren aquí són per a Configure --Prefix =/USR

-sysconfdir =/etc--localStedir =/var

Activa els protocols instal·lats
# Una llista separada per comes d'IPS o amfitrions on escoltar connexions.
"*" escolta en totes les interfícies IPv4 "::" escolta totes les interfícies IPv6.

Si voleu especificar ports no defensius o qualsevol cosa més complexa,

Edita Conf.D/Master.Conf.
sudo nano /etc/apache2/sites-available/femmebabe-le-ssl.conf
Escolta = *, ::

Directori base on emmagatzemar dades d'execució.

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>
Nom d'aquesta instància. En la configuració de diverses instàncies Doveadm i altres ordres

es pot utilitzar -i <instance_name> per seleccionar quina instància s'utilitza (una alternativa

a -c <config_path>). El nom de la instància també s'afegeix als processos de Dovecot
sudo a2dissite 000-default-le-ssl
sudo a2dissite 000-default
sudo a2dissite default-ssl
a la sortida de PS.

instance_name = Dovecot

Missatge de felicitació per als clients.
sudo a2ensite femmebabe-le-ssl
sudo systemctl reload apache2
login_greeting = Dovecot a punt.

Llista separada per l'espai de rangs de xarxa de confiança. Connexions d'aquestes

Els IPS poden substituir les seves adreces i ports IP (per registrar -se i
cd projectname
source venv/bin/activate
python manage.py check
per a comprovacions d'autenticació). Disable_PlinText_Auth també s'ignora per a

aquestes xarxes. Normalment especifiqueu els vostres servidors de proxy IMAP aquí.

login_trusted_networks =
nano venv/lib/python3.12/site-packages/django/apps/registry.py
Llista de comprovació d'accés a l'espai (per exemple, TCPWAP)

login_access_sockets =

Amb proxy_maybe = Sí Si la destinació del proxy coincideix amb algun d'aquests IPS, no ho feu
                # proposant. Això no és necessari normalment, però pot ser útil si la destinació
                # IP és, per exemple, Una IP de l'equilibrador de càrrega.
# auth_proxy_self =
Mostra més títols de procés verbosi (en PS). Actualment mostra el nom d'usuari i

Adreça IP. Útil per veure qui utilitza els processos IMAP

(per exemple, bústies compartides o si s'utilitza el mateix UID per a diversos comptes).
python manage.py check
verbose_proctitle = núm.

Si es maten tots els processos quan es tanqui el procés mestre de Dovecot.

Configurar -ho a "No" significa que Dovecot es pot actualitzar sense
                # obligant a tancar les connexions de clients existents (tot i que també podria ser
                # Un problema si l'actualització és, per exemple, a causa d'una solució de seguretat).
# shutdown_clients = sí
Si no és zero, executeu ordres de correu mitjançant aquestes connexions a DoveAdm Server,

En lloc d'executar -los directament en el mateix procés.

doveadm_worker_count = 0
sudo systemctl reload apache2
UNIX SOCKET o HOST: Port utilitzat per connectar -se al servidor DOVEADM

doveadm_socket_path = doveadm-server

Llista separada per l'espai de variables d'entorn que es conserven a Dovecot

Startup i va passar a tots els processos dels seus fills. També es pot donar

clau = parells de valor per configurar sempre la configuració específica.

import_environment = tz

ip -6 addr
Configuració del servidor de diccionari

El diccionari es pot utilitzar per emmagatzemar llistes de valor = valor. Això ho fa servir diversos

plugins. Es pot accedir directament al diccionari o bé a

servidor de diccionari. Els noms del diccionari de mapes de blocs següents a Uris

Quan s'utilitza el servidor. A continuació, es pot fer referència amb URI en format

"Proxy :: <name>".

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

A continuació s'inclou la major part de la configuració real. Els noms de fitxer són

Primer ordenat pel seu valor ASCII i va analitzar en aquest ordre. Els 00-prefixos

En els noms de fitxers, es pretén facilitar la comprensió de la comanda.

Un fitxer de configuració també es pot intentar incloure sense haver de donar cap error si

No es troba:

Permet a Dovecot escoltar totes les connexions d'entrada (IPv4 / IPv6)

Afegiu una contrasenya per a l'usuari de Dovecot:

nano config/etc_dovecot_passwd

La primera part del fitxer, abans del còlon, és el nom d'usuari. La darrera part, "yourPassword", denota la contrasenya que voldríeu donar al vostre servidor de correu.

Equip: {plana} yourPassword

A continuació, la configuració OpendKim
nano config/etc_postfix_main.cf
nano config/etc_opendkim.conf

I afegiu aquestes línies:

# Aquesta és una configuració bàsica per signar i verificar. Pot ser fàcilment # Adaptat per adaptar -se a una instal·lació bàsica. Vegeu OpendKim.conf (5) i # /usr/share/doc/opendkim/examples/opendkim.conf.sample per completar # Documentació dels paràmetres de configuració disponibles. Syslog sí Syslogsuccess sí #LogWhy no # Paràmetres comuns de signatura i verificació. A Debian, la capçalera "de" és # sobreignat, perquè sovint és la clau d'identitat que utilitzen els sistemes de reputació # i, per tant, una mica sensible a la seguretat. Canonicalització relaxada/senzilla Mode s Subdominis núm Caps de sobreignació de # Signatura de domini, selector i clau (obligatori). Per exemple, realitzeu la signatura # per al domini "Exemple.com" amb el selector "2020" (2020._DaMainKey.example.com), # Utilitzant la clau privada emmagatzemada a /etc/dkimkeys/example.private. Més granular Les opcions de configuració es poden trobar a /usr/share/doc/opendkim/readme.opendkim. #Domain exemple.com #Selector 2020 #Keyfile /etc/dkimkeys/example.private # A Debian, Opendkim funciona com l'usuari "Opendkim". Es requereix un UMask de 007 quan # Utilitzant una presa local amb MTA que accedeix a la presa com a no privilegiat # usuari (per exemple, postfix). És possible que hàgiu d'afegir l'usuari "postfix" a grup # "OpenDkim" en aquest cas. Userid opendkim Umask 007 # SOCKET per a la connexió MTA (obligatori). Si el MTA es troba dins d'una presó de chroot, # S'ha d'assegurar que el socket sigui accessible. A Debian, Postfix entra # un chroot in/var/spool/postfix, per tant, un sòcol unix hauria de ser # configurat com es mostra a la darrera línia següent. #Socket local: /run/opendkim/opendkim.sock #Socket inet: 8891@localhost #Socket inet: 8891 Socket Local: /var/spool/postfix/opendkim/opendkim.sock Pidfile /run/opendkim/opendkim.pid # Amfitrions per als quals cal signar en lloc de verificar, el valor predeterminat és 127.0.0.1. Veure el # Secció d'operació d'OpenDKIM (8) Per obtenir més informació. #InternalHosts 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0.0/12 # L'ancoratge de confiança permet DNSSEC. A Debian, es proporciona el fitxer d'ancoratge de confiança # pel paquet dns-root-data. TrustanchorFile /usr/share/dns/root.key #NameserVers 127.0.0.1 # MAPA DOMAINS D'ADA ADREÇA A LES CLAUS S'utilitzen per signar missatges KeyTable Refile: /etc/opendkim/key.table RefileTable Refile: /etc/opendkim/signing.table # Un conjunt d'amfitrions interns el correu electrònic del qual s'ha de signar InternalHosts /etc/opendkim/trusted.hosts
# Aquesta és una configuració bàsica per signar i verificar. Pot ser fàcilment
# Adaptat per adaptar -se a una instal·lació bàsica. Vegeu OpendKim.conf (5) i
# /usr/share/doc/opendkim/examples/opendkim.conf.sample per completar
# Documentació dels paràmetres de configuració disponibles.
# LogWhy no
# Paràmetres comuns de signatura i verificació. A Debian, la capçalera "de" és
# sobreignat, perquè sovint és la clau d'identitat que utilitzen els sistemes de reputació
# i, per tant, una mica sensible a la seguretat.
# Signatura de domini, selector i clau (obligatori). Per exemple, realitzeu la signatura
# Per a Domain "Exemple.com" amb Selector "2020" (2020._DaMaINKEY.EXAMPLE.com),
# Utilitzant la clau privada emmagatzemada a /etc/dkimkeys/example.private. Més granular
# Les opcions de configuració es poden trobar a /usr/share/doc/opendkim/readme.opendkim.
Exemple de domini.com

Selector 2020

Keyfile /etc/dkimkeys/example.private
nano config/etc_postfix_master.cf
A Debian, Opendkim funciona com l'usuari "Opendkim". Es requereix un UMask de 007 quan

Utilitzant una presa local amb MTA que accedeix a la presa com a no privilegiat

Usuari (per exemple, postfix). És possible que hàgiu d'afegir l'usuari "postfix" a grup
# "OpenDkim" en aquest cas.
# Sòcol per a la connexió MTA (obligatòria). Si el MTA es troba dins d'una presó de chroot,
# S'ha d'assegurar que la presa és accessible. A Debian, Postfix entra
# un chroot in/var/spool/postfix, per tant, un sòcol unix hauria de ser -ho
# Configurat com es mostra a la darrera línia següent.
# Socket Local: /run/opendkim/opendkim.sock
# Socket inet: 8891@localhost
# Socket inet: 8891
# Amfitrions per als quals cal signar en lloc de verificar, el valor predeterminat és 127.0.0.1. Veure el
# Secció d'operació d'OpenDKIM (8) per obtenir més informació.
# Internethosts 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0.0/12
# L'ancoratge de confiança permet DNSSEC. A Debian, es proporciona el fitxer d'ancoratge de confiança
# pel paquet DNS-Root-Data.
# NamserServis 127.0.0.1
# MAP DOMAINS D'ADA ADREÇA A LES CLAUS S'utilitzen per signar missatges
# Un conjunt d'amfitrions interns el correu electrònic del qual s'ha de signar
# nano config/etc_default_opendkim
# I afegiu aquestes línies
# # Nota: es tracta d'un fitxer de configuració heretada. No és utilitzat per l'OpenDKIM
# servei Systemd. Utilitzeu els paràmetres de configuració corresponents a
# /etc/opendkim.conf en lloc.
#
# Anteriorment, es podria editar la configuració predeterminada aquí i, a continuació, executaria
# /lib/opendkim/opendkim.service.generate per generar fitxers de substitució de systemd a
# /etc/systemd/system/opendkim.service.d/override.conf i
# /etc/tmpfiles.d/opendkim.conf. Tot i que això encara és possible, ara ho és
# Recomanat ajustar la configuració directament a /etc/opendkim.conf.
#
#Daemon_opts = ""
# Canvia a/var/spool/postfix/run/openendkim per utilitzar un sòcol UNIX
# postfix en un chroot:
#Rundir =/var/spool/postfix/run/opendkim
Rundir =/run/opendkim
#
# No es pot especificar una presa alternativa
# Tingueu en compte que la configuració anul·larà qualsevol valor de socket a opendkim.conf
# per defecte:
Socket = "local: /var/spool/postfix/opendkim/opendkim.sock"
# Escolteu totes les interfícies del port 54321:
#Socket = inet: 54321
# Escolteu a Loopback al port 12345:
#Socket = inet: 12345@localhost
# Escolteu el 192.0.2.1 al port 12345:
#Socket = inet: 12345@192.0.2.1
User = OpenDkim
Grup = OpenDkim
Pidfile = $ rundir/$ name.pid
Extrafter =
# Nota: es tracta d'un fitxer de configuració heretada. No és utilitzat per l'OpenDKIM
# Servei Systemd. Utilitzeu els paràmetres de configuració corresponents a
# /etc/opendkim.conf en lloc.
# 
# Anteriorment, es podria editar la configuració predeterminada aquí i, a continuació, s'executaria
# /lib/opendkim/opendkim.service.generate per generar fitxers de substitució de systemd a
# /etc/systemd/system/opendkim.service.d/override.conf i
# /etc/tmpfiles.d/opendkim.conf. Tot i que això encara és possible, ara ho és
# Es recomana ajustar la configuració directament a /etc/opendkim.conf.
# 
# Daemon_opts = ""
# Canvieu a/var/spool/postfix/run/openendkim per utilitzar un sòcol unix amb
# postfix en un chroot:
# Rundir =/var/spool/postfix/run/opendkim
# 
# No es pot especificar una presa alternativa
# Tingueu en compte que la configuració això substituirà qualsevol valor de socket a OpendKim.conf
# per defecte:
# Escolteu totes les interfícies del port 54321:
# Socket = INET: 54321
# Escolteu a Loopback al port 12345:
# Socket = inet: 12345@localhost
# Escolteu el 192.0.2.1 al port 12345:
# Socket = inet: 12345@192.0.2.1
# Quan estiguem preparats per configurar el nostre servidor Postfix, executarem el codi següent, amb el nom de domini adequat incrustat. Comença per crear un guió
# Toqueu els scripts/postfixetup
SUDO CHMOD A+X Scripts/PostfixSetUp
Nano Scripts/PostfixSetUp
# Ara, a Nano, l'editor de text, editeu aquest fitxer perquè inclogui el vostre nom de domini en lloc de femmebabe.com.
# #!/bin/bash
# Configuració postfix
CD $ DIR
ECHO "Configuració dels serveis de correu" "
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/ETC_DOVECOT_CONF.D_10-AUTH.CONF /TC/DOVECOT/CONF.D/10-AUTH.CONF
SUDO CP CONFIG/ETC_DOVECOT_CONF.D_10-MASTER.CONF /TC/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/TLEES
sudo mkdir /etc/opendkim/keys/femmebabe.com
sudo mkdir/var/spool/postfix/opendkim
Sudo eco "*@femmebabe.com sendonly._domainkey.femmebabe.com" | SUDO TEE -A /TC/OPENDKIM/SIGNING.TABLE
Sudo eco "sendonly._domainkey.femmebabe.com femmebabe.com:sendonly:/etc/opendkim/keys/femmebabe.com/sendonly.private" | SUDO TEE -A /TC/OPENDKIM/KEY.TABLE
Sudo eco "127.0.0.1" | Sudo Tee -A /etc/opendkim/trusted.hosts
Sudo eco "localhost" | Sudo Tee -A /etc/opendkim/trusted.hosts
Sudo eco "" | Sudo Tee -A /etc/opendkim/trusted.hosts
Sudo eco "*.femmebabe.com" | Sudo Tee -A /etc/opendkim/trusted.hosts
Sudo Chown -r Opendkim: Opendkim /etc /opendkim
sudo opendkim -generkey -b 2048 -d femmebabe.com -d /etc/opendkim/keys/femmebabe.com -s Sendonly -v
SUDO CHMOD GO-RW/etc/Opendkim/Tecles
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/mail/
Sudo Chown: usuaris/var/mail/*
sudo chmod -r a+rwx/var/mail/*
SUDO Systemctl Reiniciar Opendkim Postfix Dovecot
sudo cat /etc/opendkim/keys/femmebabe.com/sendonly.txt | tr -d '\ n' | SED 's/\ s // g' | SED 's/"" // g' | awk -f '[) (]' '{imprimir $ 2}'
# !/bin/bash
# Configuració postfix
# Ara, executeu el script completat per configurar Postfix, OpendKim i Dovecot.
# ./scripts/postfixetup
# Un cop executat aquest script, copieu la darrera línia que imprimeix i enganxeu -la a la configuració DNS com a valor de sendoNly._domainKey. Aquesta és la clau d'OpenDKIM que s'utilitza per identificar el vostre domini quan envieu un correu segur.
# Impressionant! En pocs dies, haureu de poder enviar correu del servidor sempre que tot estigui configurat correctament.
# Si acabeu de configurar el DNS per al vostre servidor de correu, hauria de trigar menys de 72 hores a actualitzar els registres. Normalment és molt més ràpid. Podeu comprovar si el vostre servidor funciona mitjançant aquesta ordre, proporcioneu el vostre correu electrònic:
# Echo "Test" | Correu -S "Prova Correu electrònic" youremail@gmail.com
# Si tot sembla que funciona correctament, haureu de poder enviar correu electrònic amb el vostre servidor. Si no funciona, proveu de mirar els registres per veure quin pot ser l'error.
# Tail –lines 150 /var/log/mail.log
# Això oferirà informació verbosa sobre el correu que s'envia el servidor i si funciona correctament. També heu de poder veure el correu electrònic a la safata d'entrada, si no hi és, comproveu la carpeta de correu brossa.
# També haureu de configurar la vostra configuració a la vostra configuració.py perquè el vostre servidor de correu electrònic pugui parlar amb la vostra aplicació Django, el projecte. Afegiu o substituïu aquestes línies a la configuració
# Correu electrònic_host = domini
Correu electrònic_port = 587
Correu electrònic_use_tls = true
Correu electrònic_address = 'equip@femmebabe.com'
Correu electrònic_host_user = "equip" #'love@mamasheen.com "
Correu electrònic_host_password = config ['correu electrònic_host_password']
Default_from_email = '{} <{}>'. Format (nom_nom, correu electrònic_host_user)
# "Love@mamasheen.com"
# Tingueu en compte que utilitzem un fitxer de configuració per obtenir la contrasenya. Carreguem aquest fitxer a la configuració així, al començament del fitxer.:
# Importa el sistema operatiu
Importa json

# Obrir i carregar configuració
amb Open ('/etc/config.json') com a config_file:
    config = json.load (config_file)
# Obriu i carregueu la configuració
# Creem aquest fitxer i afegim una clau secreta, així com la contrasenya del correu. Per generar una clau secreta, utilitzeu aquesta ordre, amb la longitud que us agradi al final:
# OpenSSL Rand -Base64 64
# Ara, copieu el text que OpenSSL va generar i edita /etc/config.json
# sudo nano /etc/config.json
# Afegiu les línies següents al fitxer, amb la tecla que OpenSSL es va generar com a clau secreta.
# {
	"Secret_Key": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-Generat-INDERATIU-ESPER-OPENSSL)",
	"Correu electrònic_host_password": "yourPassword"
}
# El format JSON és senzill i fàcil d'utilitzar, podem declarar altres claus que volem utilitzar en el nostre projecte d'aquesta manera i mantenir -les separades del nostre directori de projectes perquè altres usuaris no els puguin escriure i, per tant, no es poden llegir només del nostre directori de projectes. Aquesta és la pràctica recomanada per a les claus API, de les quals utilitzarem més que uns quants aquí.
# També voldreu fer una còpia de seguretat del vostre projecte per assegurar -vos que tot estigui guardat i que més endavant podreu recuperar el vostre treball, fins i tot si ja no voleu llogar un servidor.
# Còpia de seguretat del sudo
# Ara, proveu d'enviar un correu electrònic HTML des del servidor web, sempre que l'enviament d'un de la línia d'ordres funcioni. Consulteu la instància d'usuari al shell i envieu un correu electrònic HTML a aquest usuari mitjançant Django. Canvieu el meu nom al codi, Charlotte, al vostre nom d'usuari.
# Python Manage.py Shell
de django.contrib.auth.models importeu usuari
u = user.objects.get (nom d'usuari = 'charlotte')
des d'usuaris.Amail import send_welcome_email
send_welcome_email (u)
sortida ()
# Si la primera ordre no funciona, assegureu -vos d'utilitzar
# font venv/bin/activeu
# Sempre que tot estigui configurat correctament, ara rebreu un correu electrònic de benvinguda a la bústia enviada per la vostra aplicació web. Bona feina! Heu recorregut un llarg camí.
# Volia afegir, si alguna vegada teniu problemes amb algun error mentre treballeu en un projecte com aquest, no dubteu a cercar respostes i a demanar ajuda. Google, entre altres motors de cerca, són recursos excel·lents per cercar ajuda de programació. Simplement cerqueu l'error que esteu rebent i podreu veure com altres persones solucionen el problema. A més, us convidem a contactar amb mi, als vostres educadors (professors, professors, tutors), tots els companys d'Internet que estiguin disponibles per a la programació d'ajuda o consultin aquest llibre de nou o altres recursos per trobar solucions als problemes que experimenteu. Entenc que això no és fàcil, però, fins i tot si heu llegit fins ara i no escriviu cap codi, esteu aprenent molt sobre la creació d'una aplicació web des de zero. Passeu -vos a l'esquena, esteu fent una gran feina.
# Gràcies per dedicar -vos el temps a llegir aquesta Guia de desenvolupament web de la tercera edició. En les futures edicions, inclouré més exemples importants comentats al començament del document i aprofundirem molt en el món del desenvolupament de programari i maquinari. Estigueu atents al que vindrà, i tinc ganes d'ensenyar -vos a crear programes increïbles. Ens veiem a la propera edició!
# Visiteu aquest enllaç (us portarà fora de 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






Sirhan
Pahina 1
Molukso
Tan-awa ang Tibuok nga Artikulo
Padayon sa pagbasa

Pagpalit uban ang Crypto



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


Professional entertainment, photos, videos, audio, livestreaming and casual gameplay, as well as ID scanning, web development and surrogacy services.

Biyai ako usa ka tip sa Bitcoin gamit ang kini nga adres: 3KhDWoSve2N627RiW8grj6XrsoPT7d6qyE

© Glam Girl X 2025

Mga Termino sa Pag-alagad