实用的基于Web的深度学习和安全

经过 Daisy
实用的基于Web的深度学习和安全 第三版 夏洛特·哈珀 2024年7月3日 2025年6月3日更新/转换
前言:
为网络构建软件的安全考虑因素是任何Web开发人员计划和执行的重要组成部分,同时设计了可靠,稳定且用于实际目的的原型。 DOM(文档对象标记)及其实施HTML,JavaScript和CSS以及实施Python,C/C ++,Java和Bash的后端软件,为Web开发人员提供了自由和力量,以创造各种各样的项目,这些项目表现出表现力,为使用和功能的均匀性和功能提供了既定性,并提供了既便宜''and Comece and Comece and Come and Come and Come ance exece,又可以享有良好的效果,并且既适合又有既定的,并且可以很好地使用,并且既适当又有范围,并且既适当又有范围,并且既适当又有范围,并且既适当又有范围,并且既适合又有既定的又有范围。希望杀死时间或在互联网上完成某件事,通常是在触摸屏智能手机设备上。大多数人甚至都不知道想从头开始构建网站时从哪里开始,他们会在他人的网站上启动,并在功能,可靠性,易用性,易用性,尤其是创造力方面构建某些东西,可以使用所有最新的功能强大工具,以便为其提供所有有用的有用的东西,以建立一些有用的东西,而不必浪费时间来浪费昂贵的订阅来浪费贵重的用途,以便将其用于使用限制,并且可以使用限制,并且可以使用限制。如果您有几分钟的时间阅读本书并了解我想教您的内容,甚至与我个人谈论您的目标,并以正确的方向获得一些指导,并有动力去学习编码和编写自己的软件,将这本书带回家,并预留一些时间来学习下一个有影响力的,强大的,功能强大的,功能强大,精简和重要的网络应用程序,在您身上和所有需要的网站,可以满足您的需求,并满足您的需求和您的需求。
关于我: 我是一名软件开发人员,在C/C ++,Java,Python,HTML,CSS和JavaScript方面具有广泛的经验。我建立了人们想要使用,想要访问的网站,甚至沉迷于仅仅学习,重新创造和杀死时间,最重要的是,我出售软件。如果您有一个想法确切希望您希望网站的外观和功能,那么您愿意支持我,以便我在满足您的网站时可以满足自己的需求,并且您愿意自己承担自己运行网站的成本,我会为您建立下一个YouTube,Tiktok,Twitter,Twitter,Google,甚至只能访问高级技术安全应用程序。我没有试图为您出售我的时间,而是要购买您的时间:我想与您联系,以构建一个已经存在的信息,并教您成为独立软件开发人员所需的内容,以实现您想要的任何领域的成功职业。让我清楚,我给您的教育将是非正式的。您可以上学并通过正规教育学习所有这些,甚至可以在学校阅读这本书,完成任务,并从您的教育中获得很多东西,但是我不会正式地将您放在热地座位上,并要求您完成任务。我不是你的教授,你可以像一个朋友一样想到我,他想指导您从自己的个人成功所驱动的职业。而且我也不会让您成功,您将需要花时间购买它。学习编码具有陡峭的学习曲线,而且从来都不是一件容易的事,甚至应该是。您需要尽可能地努力工作,并继续尝试失败并重试,即使您感到沮丧,才能自己学习和构建应用程序。这是代码本身的性质。代码是由旨在给程序员错误消息的编译器运行的,即使您只是将错误复制到搜索引擎并阅读其他人的示例中,这些代码也会教您如何编码。而且我必须说,您不需要非常富有,聪明,成功,甚至是细节或有组织的来构建应用程序。计算机为您照顾该组织。您只需要在反复试验和错误中坚持不懈,保持专注并努力工作,您将在整个工作中拥有非常成功的职业生涯。
我是谁: 我意识到,最后一部分更多是关于学习,而您从这本书中采取了一些方法。我到底是谁?这是一个复杂的问题。我本人还不清楚,因为我患有医疗状况,这可能使我很难进行编码或撰写本书,同时在社交和身份问题上提出挑战,这使我的生活在介绍自己时变得更加困难。简而言之,如果您正在读这本书,则将其带回家是因为您翻阅了它并认为它很有用,或者即使您只是读了这本书,我还是一个志趣相投的人,希望看到您在您所做的一切中都取得成功。我本人是工程师,软件开发人员和学生,并且我正在为其他想要通过提供所需软件的手册来使自己的生活更轻松的学生写这本书,这是通过给出示例来使生活更轻松的手册,例如将诸如大型难题的示例复制到一个工作,有用的,大型,功能,功能,凝聚力,凝聚力和吸引人的应用程序中,这些应用程序无关紧要。在很大程度上,这就是我要做的:我构建应用程序来帮助自己和其他人取得成功。我也是作家,尽管这是我打算完成的第一个出版物,以便将我的投资组合放在有用的文档中,而且我也是艺术家。 我会向你承认,我有点陌生的人。我并不完美,我已经与法律竞选,甚至导致我离开大学,离开州,以便为自己取得更大的成功。我是一个女人,出生时,我穿化妆,给自己拍照,穿衣服和其他女装衣服,并且我天生就会意识到自己是女性。过去,我与其他人遇到了问题,导致写作和构建WebApps挣扎,很抱歉,我无法尽快将这本书掌握在您的手中:您需要这个。您将需要读取和编写看起来像我的,像我一样工作的代码,而且做同样的事情,但甚至更好,因为如果您有能力购买这本书而不是像我为自己创建一本书要为此赚钱的那样捣碎您的键盘,那么您就拥有一生中需要成功的资源。我在家庭成长,健康状况,医生,媒体和法律方面都有各种各样的问题,而我的守则深深地反映了在一个分裂和沮丧的世界中的女权主义和女性的斗争。但是,这本书是我深切关心的,我的孩子,我的投资组合和我的生计,因此,我感谢您在将文字带回家并仔细地仔细回家以向我学习时的考虑。请记住,我并不完美,这本书将有错误,修订和新版本,您需要尽力而为,以便在我的写作上获得成功的经验。另外,请理解,即使您在写作时面对挑战,我也对您来说很好。这样考虑这样做:当您只能租用计算机系统来执行您可能想象的任何事情时,存储遇到的所有信息,分析和组织它,并理解它时,您将不可避免地遇到困难,而您正在摄入甚至发布的信息。我告诉你这是因为我遇到同样的困难。使用这本书以自己的风险使用,与您的社区和社区一起在安全的环境中构建软件,并且在您失败甚至以错误的方式取得成功时,请不要将事情带到个人身上:这就是我的发展方式:为什么我能为您带来这个文本并为您带来成功而不会在我的疯狂之路上取得成功的方式,而在我的疯狂之中,我会在我遇到的范围内遇到的范围,这是我在整体上遇到的范围,因为我会遇到整体范围,因为我会遇到整体的范围,而全球范围的范围则是在全球上的范围,这是我的范围,这是一个全球范围的范围。 互联网。您可能对我只有几句话不是很熟悉的人,但是我鼓励您继续阅读,当您在建立自己的项目以完成工作的同时继续阅读和理解我时,您会认识我。只要您的教授或老师什么都没有分配您,这本书就不会有作业,但是我强烈鼓励您在阅读时自己构建项目组合,以及一个盖帽项目,展示了如何应用您所学的东西。我的Capstone项目是您将在本书中阅读的大多数内容的基础,因为它结合了我以前的项目,我创建和学会的代码,学习并学会了手工写的代码,以及各种各样的想法和技巧,这些想法和技巧可以帮助我成功,以至于我可以旋转一个简单的应用程序,该应用程序可以完整地使用,并且看起来像一个流行的应用程序,您可能会看到您的朋友或家人在互联网上使用,或者在互联网上使用,或者在互联网上使用新闻,或者在您的互联网上使用。
这本书是什么: 这本书是一个例子。您可以在此处找到代码,有关如何学习代码,有关调试代码的信息以及解决错误的说明,故障排除步骤,有关如何备份和保存代码的说明,如果有人断开代码,保护您的代码,部署代码,构建您的交互式网站,构建娱乐性,吸引人的互动网站以及您的娱乐性,以及您的工作,以及您的工作,以及您如何,以及如何,您可以和您的意识,以及如何,您可以和您的融合,以及如何,以及如何,您会构成您的娱乐性,以及如何,您会构成您的意识,以及如何,您会扮演我的意识,以及如何,您会构成您的意识,以及如何,您会构成您的意识,以及如何,您会扮演的方式,以及如何,您会构成自己的意识,以及如何,您会构成自己的意识,以及如何,您可以和您构成的互动网站,以及如何,以及您如何构成自己的意识。您以绝对最佳的光线建造最终用户,网站的访问者最吸引人。在本书中,我将演示许多软件设计示例,重点是网络作为平台和安全性。我们将使用UNIX Shell建立一个基本项目来启动学习体验,并具有备份和脚本功能。然后,我们将检查一个基本的博客网站,使用照片和视频功能升级我们的博客,并使用这些功能使用免费软件使用安全解决方案,并使用可插入的身份验证模块(PAM)使用安全服务器。然后,我们将查看文件处理和处理,探索视频编辑,语音捐赠,条形码扫描和光学角色识别等概念。在此过程中,我们将检查API,这将帮助我们通过免费和付费选项使我们的软件更有用和安全。在此过程中,我们将探索物理安全和武装工具,例如枪支和弹药设计和制造,包括枪管和中继器设计,炮塔和无人机设计以及其他校长,我们将与我们在现有网络上的软件集成,以保护我们的软件并展示自我防御和自我辩护和夸张性。我们将在构建游戏,2D和3D渲染引擎的过程中休息一下,并在基本维渲染软件的研究示例中与嵌入式硬件一起工作,并分别以硅胶橡胶施放的电子振动按摩器。一路上,我们还将采用已经可用的机器学习解决方案,以更好地保护我们的软件。我们还将采用可用于网络的库存工具,以简化和保护该过程。这本书是您成功构建Web应用程序并将其与专业的计算机和嵌入式机械系统网络集成的指南,总的来说是构建软件和嵌入式硬件的指南,没有背景知识或以前的经验。
这本书不是什么: 如果您真的想拥有一个网站,则可以设置一个简单的商店并出售所需的内容,发布博客,发布照片或视频,或者以其他方式无需编写一行代码。这本书不是那样。这本书将教您如何构建比您已经找到的任何软件更有用,功能完整,功能性和安全性的软件,因为它部署了仍然是原型的最新软件,在规模较老的公司运营中运营的最新软件可能很昂贵,并且不吸引倒退,令人费解的是为了为那些没有真正做任何事情的人赚钱而努力的公司。如果您密切关注本书,您将需要编写代码,研究代码,构建自己的应用程序,并且您将从自己的工作中赚钱。即使在早期,我也会从这本书中赚钱,因为它包含人们需要阅读的信息,并且在购买或使用我的应用程序时已经购买了。这本书不会为您构建一个应用程序,但是它将指向您的方向正确,并用所需的工具以及技能和技巧来武装您在为网络构建软件方面成功的技能和技巧,在每一条代码方面,您都需要写作的每一行,准备将其拼凑成您以及您和支持者,支持者,客人,客户,朋友,访客,访客,承包商,承包商,互联网以及互联网和互联网和互联网和互联网和互联网的使用。
您将学到什么: 这本书将教您如何构建和销售软件,真正功能性,有用的软件,媒体记录,诸如面部识别,机器可读区域条形码扫描,Web API等安全功能,以对视频和照片进行身份验证,录制和渲染视频和照片,以及蓝牙和附近Field(NFC)通信等交换消息。这本书将教您如何使用网络计算机,重点关注Debian Linux,如何构建bash代码以使安装和备份软件变得无缝,自动化的微风,如何构建Python代码作为后端来提供动态信息,并通过boottrap进行诸如bootstrap的COSSS和网络互动,启用互动的媒体和其他互动的互动式媒体,并构建与其他互动的互动,并启用了互动的媒体,并启用了其他互动媒体,并将其与其他互动互动,并启用其他互动互动,并与其他互动的媒体进行互动,并与其他互动的媒体进行互动,并与其他互动的媒体进行了交互,并与其他互动的媒体进行了交互,并与其他互动的媒体进行了交互式媒体,并且其他目的,ID扫描,图像和视频审核,数据微交易,以确保您的软件安全,付款处理,加密货币交易,异步任务等。您将学习如何使用电池,充电器,微控制器,电路,电动机和传感器来构建自己的蓝牙设备,并使用焊料,电线和3D打印以及铸件。我将演示适用于增材制造,工具和模具制造的3D设计主体,因此您能够制造自己的嵌入式,具有集成电池,充电器,电子电路和功能输出的嵌入式硬件设备。并将它们与蓝牙和网络联系。具体来说,我们将检查两个案例研究,一个振动的按摩器和一支由OpenSCAD编程的自制枪支,它们可作为图形接口或命令行实用程序提供,并且可以集成到网络中以较快。 您将学习如何在没有以前的经验的情况下从头开始建立和部署网站,使其功能性,安全,美丽,有用且最重要的是实用。您将学习如何使用机器学习和计算机视觉使网站安全,更实用,从您的网站上录制视频和音频,捐赠您的声音,制作音乐并调节音频以创建有用的示例,以及如何通过利用其他网站来构建可以直接链接到您的网站的最佳网站来打破噪音,以便您可以分享所有有用的有用信息,以分享您必须提供更重要的软件,并使您提供更重要的业务和您的业务。这本书将最重视媒体,安全和机器学习,这是三个主要组成部分,可以通过与合适的用户互动并以现实,实用,动手的方式启用错误的用户来帮助您为Web构建有用的软件,同时自动且既有自动且坚固又坚固。 本书教Unix,特别是Debian(Ubuntu),Bash Shell,Python,HTML,CSS,JavaScript,以及用于Python的许多有用的软件包,例如请求,以及GIT和FFMPEG(例如Git和ffmpeg)。我还将教您如何自动交易加密货币,并从加密货币或常规借记卡中付款,同时,如果您选择这样做,甚至还会向访问者支付收入的份额。我将教您如何通过广告从您的网站上赚钱,如何为搜索引擎准备好应用程序,并使其快速,在客户中排名第一个排名,以找到您的客户以找到您,并在尽可能多的常见搜索中排名。我将教您如何出售您的软件,宣传它,吸引寻找您服务的客户,并通过已经存在的途径在互联网上为您自己的名字,价格便宜且运作良好。我将教您如何将数据保存在适合您的云计算机上,并廉价地保存数据,如何计划和构建一个网站,以执行用户想要的内容和想要的内容,以及如何通过将您的网站放在网站上,将您的网站放在电脑上,并用通知,短信,短信,打电话,电话,将用户带到您的网站上,以将您的网站带到您的网站上,将您的网站带到您的点击率上,只需单击即可单击您的单击。这本书将重点介绍大量发布和分发媒体的实用性,从文本到照片再到视频再到音频,对最终用户(您的客户群)给人留下深刻印象,并以您所做的任何方式出售自己,以创建一个网站,一个应用程序,一个代表您的应用程序,并且只能代表您,并且使您,您的软件和公司看起来都很好。您还将从我那里学到一些技巧和技巧,从编码技巧,诸如化妆和摄影,建模和表演等实用的虚荣心等,这对于使用所有可用的工具以最佳的方式来描绘自己和您的公司很重要,同时分发了尽可能多的内容,可以在平台上跨越无需更多的努力,而不是需要努力,或者是不需要的工作。 这本书叫做"实用Web 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 enhancement,图像字幕和其他任务,例如来自图像的预测指标,例如图像的本质,作为计算机传递的图像或光学副本(图像的照片或打印的照片,都非常重要可以使您的计算机(通常要求您使用用户名和密码)制作服务器计算机,并为每个新的登录或新IP地址提供确认令牌,但是,如果您构建大规模的,易于使用,从根本上使用,功能强大的软件,这可能与其他人的软件相关联(您都可以使用您的软件,或者您可以使用任何网站,否则您就可以使用任何网站。 任何构建无可挑剔的安全软件的人都对这意味着什么有所了解。软件本质上是不安全的,因为我们用来访问它的设备和帐户并不总是可供使用,它们可能掌握在对软件不适的人手中,因此可能会对软件本身构成风险。这是本书的重点。默认情况下,网络计算机使用长密钥令牌,称为和ssh或Secur shell键,否则最好使用Web服务器保护,因为Web服务器提供了开放式访问以及在服务器本身上运行的最先进的安全工具。 Web服务器可以访问用户的Web浏览器,这可以说是用户设备中最强大的部分,因为它是用户可以访问网络软件的地方。这个工具包可以渲染文本,您看到的网页,还可以录制图像,音频和视频(例如面部或状态ID的照片),可以读取并写入到蓝牙无线电设备上,并可以读取并写入附近的电视带标签,廉价的钥匙卡,FOB,FOB,贴纸,贴纸,贴纸,响声以及与唯一的网络验证的网站和书面验证的网站和书面验证以及数据生成和写入数据和书面上,并将其读取。使用所有可以使用的工具,在这本书中,您将配备自己的知识来建立一个安全的网站,总的来说是一个安全的网络计算机系统,适合您,进行竞标,外观和感觉
从哪里开始: 欢迎您跳过我从本书或任何部分开始的部分,转到所需的确切代码,尤其是如果您在本书中要详细描述的上述工具或任何上述工具经验,以及记录用例及其实际示例。如果您没有编写代码的经验,我强烈建议您阅读所有本书,尤其是建议您阅读以前的部分,以确保本书适合您。如果这本书不适合您,请考虑将其赠送给可能有兴趣自己学习Web开发的朋友或亲戚,甚至考虑借用它并从他们那里学习,以填补我作为老师或其他老师在我之前做过的我使您失败的空白。从您开始的位置开始,如果您打算构建有用的应用程序,本书的每个部分都将很有用,并考虑最终用户构建最佳应用程序:了解您的客户。现在您知道了我,您知道这本书,您已经准备好开始了。首先,抓住一台计算机(即使是盒装商店,亚马逊或旧桌面的最便宜的笔记本电脑,并以适合您的方式进行设置。
如何读这本书: 文本突出显示,表示文本属于命令提示符,您将在其中编写运行的代码。命令提示符非常注重键盘,几乎不需要单击,加快了您的工作流程并使您更容易。
入门: 让我们潜入。我们将首先在本地机器上构建代码,然后在不建立连接到Internet的网站的情况下开始。从一开始就更安全,不花钱,对您来说很容易。根据您的操作系统,进入bash壳会有所不同。对于Mac OS,我建议此时安装虚拟机,因为您将获得与虚拟机的最大兼容性。诸如VirtualBox和ParaLells之类的各种提供商可以为您运行虚拟机,尽管如果您更喜欢使用建议使用的本机环境来创建快速,简化的体验,则也可以直接在计算机上安装Ubuntu。如果您使用的是Linux或Windows,我建议您很容易创建一个项目。打开终端,调整合适的尺寸,然后开始遵循步骤2。如果您使用的是Windows,请遵循步骤1。
步骤1: - 仅Windows用户 在Windows中,打开命令提示符作为管理员和键入 WSL –INSTALL
步骤2: - 继续此处,或跳过步骤1,如果您不使用Windows 在开放终端(取决于您的OS,Windows中的Ubuntu,Mac或Linux中的终端或类似名称),首先创建一个项目。我们使用MKDIR命令来创建目录。如果您需要创建一个目录来存储您的项目(建议使用的项目,请使用CD命令更改为目录,并且
CD/PATH/TO/DIRECTORY-路径是您的目标目录之前的文件夹(文件),默认路径为〜或/home/home/用户名(其中用户名是您的用户名)。要更改为默认目录,键入CD或CD〜 mkdir示例 - 用目录的名称替换"示例"
现在,您有一个项目目录。如果您需要切换到其他计算机或部署您编写的代码,则保存此目录非常重要,因此我们将在接下来的几个步骤中构建一个脚本来备份您的目录。但是,构建脚本需要一些代码,并且需要自动化代码以尽可能有用。因此,让我们构建一个脚本以构建脚本。让我们从创建脚本并使其可执行。我们将使用sudo,chmod并为此触摸,并将脚本称为" Ascript"。
sudo touch /usr/bin/ascript
sudo chmod a+x /usr/bin/ascript
sudo nano /usr/bin/ascript
现在,我们创建了脚本,使其可执行,并准备对其进行编辑。 Nano是一种文本编辑器,可以让您无需单击即可编辑文本,这比使用图形用户界面要容易得多。要使用Nano编辑文件,请使用Nano,然后使用该文件的路径。要制作一个制作脚本的脚本,它与首先制作脚本相似。我们将使用与上述相同的代码,用参数参数替换脚本的" ASCRIPT"名称,$ 1。这使我们可以通过简单地键入sudo ascript newscript来调用脚本,这时我们可以通过用您的脚本名称替换" newscript"来创建任何新脚本。 Nano中的代码应该看起来像:
sudo touch /usr/bin/$1
sudo chmod a+x /usr/bin/$1
sudo nano /usr/bin/$1
为了关闭纳米,我们可以按住控制键并按x,然后y表示我们保存文件,然后点击返回。现在,我们将能够键入SUDO ASCRIPTION再次编辑脚本,而不是键入这三个命令来编辑脚本。这有效!并且任何新脚本都可以通过在外壳中调用。让我们立即保存工作:让我们编写一个备份脚本以保存我们的新脚本,然后在项目目录中备份它,同时还备份备份脚本。
sudo ascript backup
现在,在纳米:
sudo cp /usr/bin/backup /path/to/directory/
sudo cp /usr/bin/ascript /path/to/directory/
where/path/to/directory是您使用MKDIR创建的项目的路径。稍后,我们将学习如何使用循环和列表复制这样的重复路径,这是较少的代码,但现在让我们保持简单并有几行。要运行此脚本并备份您的代码,请使用控制+x,y和返回将文件保存在nano中
backup
如果您在阅读本书并在外壳中遵循的过程中完全提示您输入密码,请正确输入您的用户密码,您将进行三次尝试,然后再重新运行该命令。如果需要两次运行任何内容,则可以使用上下箭头来重新运行命令并编辑它们。在用右,左箭头和删除键以及键盘上编辑命令之前,简单地按中间和向上选择一个命令,然后使用返回运行它。
恭喜!您设法创建了一个很棒的备份脚本,该脚本可以备份工作目录中的两个重要的外壳脚本。随着项目越来越大,我们可能会稍后将事情移动,但现在可以使用。让我们继续在云中备份,我们将使用GitHub为此(尽管还有许多其他git解决方案用于备份,但它们都是相同的。)Git是一个Verision Control软件,可以使您在将它们备份到服务器上时将其备份到服务器上,同时还可以使您可以在密码或密钥后下载整个软件的整个副本。它有助于保存您的软件,尤其是当我们迁移到有时会在一行代码失败时破裂的有时会破裂的安全性,如果您没有机会自动备份代码,则可能无法备份,而我们将不会自动备份它,我们将介绍它们。
如果您目前尚未使用Ubuntu虚拟机,我此时建议使用Ubuntu Virtual Machine使用Ubuntu Virtual Machine,因为在安装所有必要的软件包时,它将使您的生活更轻松,以构建工作网站并在计算机上进行深度深度学习操作。我们将在不久的将来将代码移至Web服务器,但是我们要确保我们的Web服务器后面至少有几层安全性可以抵抗网络钓鱼,并采用许多Linux软件包来做到这一点。如果您仍然想使用Mac OS,欢迎您在线搜索并安装必要的软件包,但是本书或系列的每个软件包可能没有其他选择。
让我们添加一些命令,通过运行命令sudo ascript备份来使用备份脚本进行工作。
# …
再次控制X要保存。
现在,我们需要为该项目进行一次一次配置。因为它很快将是一个git项目,所以我们不需要每次从git存储库中部署时键入每个命令,但是当我们编写部署脚本时,我们会掌握此命令。首先,让我们确保我们处于正确的目录中,并初始化GIT存储库并生成SSH键。
cd /path/to/directory
git init
git branch -m master
ssh-keygen
键入SSH-Keygen之后,应将新键保存在一个名为.ssh的文件夹下的主文件夹中。它称为id_rsa.pub。让我们找到此键并复制它。看到它,
cd ~
cat .ssh/id_rsa.pub
在将git提供商(理想情况下是github)与您的git提供商(理想情况下)创建一个帐户,在将SSH键添加到您的帐户中。拥有帐户后,请单击右上角菜单,然后输入设置,然后在菜单中访问的ssh和gpg键中添加SSH键。选择添加一个SSH键,然后通过将其粘贴并给它添加标题,然后保存并返回Github创建新的存储库。对于其他GIT提供商来说,这是类似的,您需要阅读其文档。在新的存储库配置中,为您的存储库提供一个描述性名称,并决定是否要发布它,并确保配置尚未包含的文件。创建存储库后,用SSH URL复制克隆,然后将其粘贴到以下命令中。
git remote add git://… (your remote URL)
现在,您可以使用CD回到存储库,您将熟悉此。立即尝试使用备份的备份脚本
伟大的!现在我们真的可以进行编码。现在,让我们安装Django,因为我们对bash和git有很好的掌握。 Django将让我们自动备份我们的软件,Bash也可以做到这一点,但是Django应该具有更简单的实现(可以更轻松地禁用和配置)。
要在Ubuntu中安装软件,我们将使用sudo apt-get命令。首先,让我们更新和升级我们已经拥有的软件。这可以通过sudo apt-get update和sudo apt-get升级-y来完成。接下来,让我们安装python和我们的虚拟环境,即代码的故乡,并使用以下命令:sudo apt-get install python-is python3 python3-venv
就ubuntu实例中的软件安装而言,这就是您需要使用Django的全部。对于Windows和Linux,这应该非常简单,但是对于MAC,您可能需要使用免费或付费的虚拟环境(例如VirtualBox或Paralells桌面)在其上安装虚拟机和Linux,并重新创建上述步骤以设置Ubuntu环境。在这种情况下,Ubuntu至关重要,因为它是网站运行的软件,它使他们能够托管所有上述软件的网站。
让我们挖掘django。
在我们的目录中再次使用CD:
python -m venv venv # 创建存储代码的虚拟环境
source venv/bin/activate # 激活虚拟环境
django-admin startproject mysite . # 我在当前目录中开始的项目是我所在的项目。
Django刚刚开始启动,因为Django托管了Web服务器,并且正在竭尽所能,以获取基本的本地网站启动和运行。现在,我们已经安装了Django,让我们对设置进行一些编辑以使其正常工作。首先,让我们创建一个新应用
python manage.py startapp feed
您会注意到第一个应用程序称为feed。无论您喜欢什么,都应称呼该应用程序,我们将创建新应用,但是每次在代码中引用该应用程序时,每个应用程序的名称都必须保持一致。要添加一个新应用程序,我们将始终在该应用程序创建的其他目录中编辑settings.py。使用Nano,
nano app/settings.py
在设置中,查找已安装的_apps,然后将[]分为3行。在空中心线上使用四个空间,添加" feed"或应用程序的名称。设置的这一部分应该看起来像:
INSTALLED_APPS = [
'feed',
]
在忘记之前,让我们测试Django正在工作。使用命令python manage.py runserver 0.0.0.0:8000,我们可以运行服务器,然后在计算机上的网络浏览器中导航,将代码运行到http:// localhost:8000,并查看示例WebPage(它工作!)使用控制C,与其他任何命令相同。
现在,让我们挖掘写一些Python代码。 Django具有三个主要组件,所有这些组件都完全由代码运行。组件称为模型,视图和模板,在将网页交付给用户之前,每个组件分别在较高和较低的级别上。
该模型是将信息存储在数据库中以进行检索,分类和渲染的代码。
该视图决定了如何渲染,操纵和修改模型,几乎每个视图都将直接使用模型。
模板是HTML代码,带有一些额外的铃铛和哨声,称为模板语言。该模板是通过从视图中填充Python代码和上下文(例如模型和信息)的视图来渲染的。
Django也有其他组件,包括但不限于:
设置,该设置如我们讨论时配置该应用程序。
URL,是用户遵循的模式,以访问Web应用程序的特定部分。
表单,该表格定义了如何处理发送到服务器的信息并将其渲染到数据库以及用户。这些是在服务器端处理信息的基础,并且可以接受计算机存储的任何类型的信息,最著名的是文本字符串,数字和True/false Booleans(通常是复选框)。
模板是HTML代码和模板语言,并弥合了Python和HTML之间的差距,这意味着Python信息可以用作HTML代码,任何人都可以访问并可以使用有限的访问网站,同时使Python代码可访问,同时使Web可访问python代码,并且可用于在远程设备上可用于在远程设备上,而无需在服务器附近不需要。
静态文件,通常是JavaScript,是服务器服务并与模板链接的库。
服务器服务或外部托管的媒体文件,或者只是在处理并发布到服务器之前写入服务器并将其发布到另一台服务器(一个存储桶)托管。
中间件是与每个视图同时运行的代码,并被视为"包含"。
上下文处理器,处理每个视图的上下文,并用于添加额外的上下文。
测试,验证用户或请求在呈现视图之前通过某些要求。
消费者,决定了网络插款如何处理和响应沟通。
admin,用于注册模型,以便可以在Django管理页面中详细操纵它们,可以通过图形接口对数据库进行管理。
定义异步任务的芹菜可以开始运行,然后立即继续执行下一个任务或代码行。
Django可以拥有许多其他组件,我们将在此处详细讨论。有很多方法可以使Django更具功能性,并添加Websocket,这些Websocket是快速,简化的通信渠道,芹菜(芹菜)执行异步任务,以及许多其他用于扩展Django的软件,尤其是在视图功能中,尤其是在大多数代码中执行大多数代码。查看功能是关键的,因为它们通常会声明特定于特定URL模式或服务器部分的每个代码。
首先,让我们探索视图功能。视图函数以表示将在视图中使用的代码的导入开始,并使用常规功能定义或类定义。最简单的视图由函数定义DEF定义,并使用基本模板返回httpresponse。首先,让我们定义一个基本视图,以返回文本" Hello World"。请记住,每次您在语句之后添加代码,例如,如果,何时,等等,您将需要为要应用于函数的每个先前定义添加4个空间。我们将很快进入这些含义。
从我们网站的目录中,使用nano编辑feed/views.py文件,然后将以下行添加到文件末尾。
from django.http import HttpResponse
def hello(request):
return HttpResponse('hello world')
Django的httpresponse用文本字符串响应,并用开口和关闭表示。每次您将信息传递到函数或类(例如请求或字符串)时,都需要使用括号(打开和关闭)。
这还不是我们需要看到的所有观点。当然,我们还没有告诉服务器确切的视图,我们仍然需要定义一条视图应呈现的路径。让我们从定义App/urls.py中的基本路径开始,以后我们将进入路径组。
在app/urls.py中,在开始导入我们刚创建的视图之后的导入语句之后添加一行。
from feed import views as feed_views
现在,让我们定义视图模式。视图模式具有三个组件,即路径组件,该组件告诉服务器在服务器内的视图所在(用户输入到导航栏中输入网页的URL路径),即指定视图的视图组件,以及视图的友好名称,以便在使用模板上更改和更新的命名,以便更改和更新的命名,以便更改和更新。以这种方式做事并保持灵活是有意义的,因为您的代码库将是一个不断变化的环境,需要灵活性和即兴创作才能有价值且易于使用。这是您的视图,您可以将其添加到urlpatterns = [app/urls.py的部分。视图模式由上述三个组件定义,并称为路径。您的URL模式是列表,因此请确保始终用逗号结束每个项目,因为这将每个项目分开。每个项目也应在新线路上再次使用四个空间,就像settings.py中的应用一样。我们将使用空字符串函数定义视图的第一个组件,以创建在Web服务器的根目录上运行的视图。您的urls.py现在应该看起来像这样:
from feed import views as feed_views
urlpatterns = [
path('', feed_views.hello, name='hello'),
]
这是与Django创建完全静态的网站的基础。为了制作一个更具动态的网站,我们可以开始缓存信息,例如图像,视频,音频等,我们将需要使用模型,我们将接下来探索。现在,让我们检查我们的代码并运行服务器。要检查代码是否错误,请运行:
python manage.py check
如果有任何错误消息,您应该仔细查看对应用程序所做的更改,并查看是否需要修复任何内容,例如外部或缺乏空间,额外的字符,未闭合的字符串,任何错字,任何意外删除的字符或其他任何内容。读取错误消息(如果您有),则应该能够查看您创建或编辑的文件编号的路径,因此请查看该文件和行,看看是否可以修复那里的任何内容。如果已解决问题,请再次运行上述命令。当您的软件准备运行并正在运行时,您会看到输出"系统检查无问题"。现在你准备好了。使用以下方式运行服务器
python manage.py runserver 0.0.0.0:8000
现在打开一个Web浏览器,并导航到http:// localhost:8000。您应该在视图中看到httpresponse函数的括号和引号中返回的文本。这只是一个基本示例,但是如果您做到这一点,您就会了解Linux,Bash,Python和Django工作的基础知识。让我们深入研究一些数据库建模,并探索Python类在存储信息中的功能。然后,在使用JavaScript和机器学习使我们的网站充分,灵活和安全之前,我们将开始对HTML和CSS掌握。
课程存储在您的应用程序的模型中。使用Nano,编辑App/models.py并添加新类。类定义一个类定义的类,并通过它继承的超类,在这种情况下,在这种情况下,模型model.model。类的名称是在类定义之后的,并且在类定义A:(colon)之后,在下面表示与类绑定的属性和函数定义之前。我们的课程需要一个可以用来检索并保持独特的ID,它还需要一个文本字段来存储一些信息。稍后,我们可以添加时间戳,文件,布尔值(可以帮助我们的代码来决定如何使用模型,并可以将其用于对其进行排序的情况),该实例将模型与用户登录服务器的用户等等。让我们解开以下代码:
from django.db import models # 用于定义我们的班级的导入及其属性
class Post(models.Model): # 我们班级本身的定义
id = models.AutoField(primary_key=True) # 我们的模型的ID是一种自动生成的密钥,它将让我们查询模型,保持独特之处并在创建模型后需要与模型进行交互时很有用。
text = models.TextField(default='') # 在这种情况下,我们的类存储的属性是一些文本,将默认为空字符串。
关闭并保存文件,就像我们之前完成的。
随着应用程序的发展,我们将探索许多其他字段和选项,但这是创建应用程序发布文本的基本必需品。但是,该模型不会单独工作。如前所述,我们将需要一个自定义视图和自定义URL模式来使该模型起作用,并且我们还需要一个与模板一起进行的表单。让我们先探索表格。
要定义表单,请使用纳米编辑应用程序/表单。py并添加以下行。我们将需要两个导入,我们的表单类别以及我们创建的模型(feed.models.post),类似于模型的类定义,以及一个字段以及一个称为meta的子类,该类别将定义与表单相互作用的模型。该表单还可以具有初始化功能,该功能会根据请求,模型或其他方式中的信息来设置它,我们将稍后探讨。
模型表格之所以有用,是因为它们可以创建模型或编辑模型,因此我们将它们都用于两者。让我们以形式定义一个。
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',)
这是形式和模型的基础知识。该模型表格可用于实例化或编辑帖子,更改其包含的文本。我们将考虑将此形式集成到接下来的视图中。首先,让我们进行迁移并迁移数据库,以便我们的代码运行时可以与模型进行交互。为此,运行以下命令:
python manage.py makemigrations
python manage.py migrate
这将需要一分钟的时间才能执行,但是一旦完成,它将允许您在软件中的视图,中间件或其他任何地方访问该模型。让我们继续观察我们可以看到模型的地方。编辑feed/views.py并添加以下代码,如上所述。您无需在#符号之后添加任何内容,该代码是用来表示有关代码信息的注释。我们将首先将我们的模型导入视图中,然后将其添加到可以在模板中渲染为显示列表的上下文中。接下来,我们将添加一个模板,可以在其中使用按钮渲染表单和模型,以根据模型创建新对象并将其发布到服务器上。这听起来很复杂,所以让我们逐步迈出一步。在完成视图之前,让我们创建一个模板,该模板只能呈现模型,并确保我们可以通过在外壳中创建新帖子来看到它。这是该视图的外观:
posts = Post.objects.all() # 查询到目前为止数据库中的所有帖子
这一切看起来都很简单,直到我们到达底部。渲染,函数返回的值,而不是像上一个示例一样在http响应中,始终将请求作为其第一个输入,接受上下文(在这种情况下,在数据库中的帖子)现在可以在模板中呈现,并返回函数中定义的模板。该模板将是带有一些名为jinja2的语言的HTML文档,该语言将Python信息传达到HTML中。
要开始创建模板,请在feed中制作两个目录。
mkdir feed/templates
mkdir feed/templates/feed
接下来,在上面的目录中编辑模板,feed/feed/feptrates/feed,并为此示例添加代码。让我们查看此示例的模板。
这是一个非常简单的模板。它定义了打开和关闭的HTML标签,一个文档类型标签,一个带有传奇标题的车身标签,一个断路标签,屏幕上添加了一条小线路,而循环则将帖子中的每个帖子呈现为模板中的段落。这是渲染帖子所需的全部,但是数据库中还没有。让我们用外壳创建一些。我们可以用manage.py运行外壳
python manage.py shell
现在,让我们导入我们的帖子模型
from feed.models import Post
接下来,我们将创建一个带有字符串的简单帖子并退出外壳。字符串可以是任何事物,只要有效文本即可。
Post.objects.create(text='hello world')
exit()
最后,我们需要在我们的供稿中添加URL模式。因为我们的feed应用程序将使用多个URL,并且我们希望将文件尺寸保持在较小的情况下,所以让我们在供稿应用中创建一个局部urls.py,看起来像这样:
from django.urls import path
from . import views
urlpatterns = [
path('', views.feed, name='feed'),
]
我们还需要在基本应用程序中编辑URLS.PY,无论我们决定称呼它,这都是我们创建的第一个目录。编辑app/app.py并将以下内容添加到URL模式
from django.urls import include # 在顶部
# ...以前的代码在这里
现在,当我们使用Python Manage.py Runserver运行服务器时,我们将看到我们创建的页面,因为我们具有模型,视图和模板以及URL模式以及数据库中的项目。接下来,让我们实现我们创建的表格并开始创建自己的帖子。但是,在我们编写太多代码之前,让我们使用之前写过的脚本进行备份。在外壳中运行此脚本,等待片刻,所有代码都将备份到我们的git存储库中。
backup
实施表单相对简单。我们将导入我们的表单,将邮政请求处理程序添加到视图中,并将帖子保存在数据库中,然后再将其重定向到同一视图。我们可以使用我们已经导入的重定向函数,以及另一个称为"反向"的函数以获取视图模式的URL。我们将使用字符串" feed:feed"来查询此问题,因为随附模式的名称空间是feed,并且该视图也称为feed。
posts = Post.objects.all() # 查询到目前为止数据库中的所有帖子
if request.method == 'POST': # 处理邮政请求
form = PostForm(request.POST) # 创建表单的实例并将数据保存到其中
if form.is_valid(): # 验证表格
form.save() # 保存新对象
return redirect(reverse('feed:feed')) # 通过get请求重定向到同一URL
'form': PostForm(), # 确保将表格传递到上下文中,以便我们进行渲染。
现在,我们需要更新模板以说明新表单。我们可以使用
让我们分解一下。有一个新的表单类,一个令牌,表单本身和提交按钮。很简单,但是当我们看一下它时,我们可能希望使它看起来更好。它有效,我们可以发表新的帖子,现在将它们保存在数据库中。这里有一些事情发生。我们使用HTML标签来声明该文档是HTML文档,我们使用模板标签({%…%})渲染表单的令牌,而另一个{{…}}渲染表单。我们也有一个循环使用块标签和模板标签渲染文本。块标签确实很重要,因为我们可以定义模板的部分与它们呈现,模板标签是我们将变量放入代码中的基础。
现在,我们需要使我们的应用看起来更好,因为现在它看起来确实很基本。我们可以使用与文档中每个对象绑定的CSS或在与每个对象相关的类中进行此操作。 CSS真的很不错,因为它告诉页面上的所有内容都应该看起来,并且可以使其看起来非常好。有一些图书馆可以做到这一点,但是我个人去的是Bootstrap。
Bootstrap可以从他们的网站下载getbootstrap.com/。到达那里后,按按钮读取安装文档,然后从Include Via CDN部分复制代码。您将在HTML文档顶部的标签中需要此代码。另外,让我们继续创建一个基本模板,这样我们就不需要在每个模板中重新创建这些链接。
用MKDIR模板制作一个称为模板的新目录,然后编辑模板/base.html。
看起来应该这样:
确保复制CSS和JavaScript,.css和.js文件,因为我们将需要JavaScript使我们的网站在将来更具功能性。
现在,让我们返回Bash Shell并运行快速命令。请记住,如果您需要访问虚拟环境,请键入源VENV/bin/Activate。这将使您可以在本地安装Python软件包,以使Django访问它们。为了给出由Django Bootstrap类生成的表格,我们将使用称为Crispy Forms的Python软件包。我们可以使用以下命令下载此
pip install django-crispy-forms
安装此任务后,将其添加到settings.py.py
# …以前的代码在这里
现在,回到我们的饲料模板中,我们可以删除一些东西。让我们删除文档的开始和结尾,并使用扩展和块定义将基础模板的继承替换为基础模板的继承。另外,我们将在表单中添加带有负载和模板过滤器的模板过滤器导入。最后,让我们在表单上的按钮中添加一个bootstrap类,以使其看起来更像一个按钮。看起来应该这样:
美丽的!这已经有很多代码了。接下来,我们应该对其进行测试,并确保我们可以看到一切看起来都不错,并且请确保一切正常。根据以前的说明运行服务器,并确保网站外观和工作正常。好!您已经准备好进入下一步,我们将使用类似的URL,表单,视图和模板添加用户登录功能。基本模板很重要,我们将继续对其进行修改并根据需要进行更改,但是现在让我们专注于使我们的网站更安全,通过使用户能够使用用户名和密码登录,最终更重要的信息,这些信息最终将帮助您的应用程序安全,并且您自己的帐户只能由您访问。
为此,我们需要使用内置在Django中的用户模型。用户模型是像我们的帖子一样的数据库模型,可以将用户登录到网站中。将来,在我们将站点部署到Internet之前,我们将使用归因于其的其他模型扩展此模型,并为登录的其他安全措施构建对网络钓鱼具有抵抗力的安全措施。我们将首先使用Django提供的一些内置登录表单。首先,让我们创建一个新应用程序,我们将使用该应用程序来渲染基本登录页面的模板和视图。我们还将创建其他应用程序来代表持续的登录挑战以确保应用程序的确保,包括平码,面部识别,近场通信,外部设备,多因素身份验证和指纹识别。
我们已经谈论过启动一个应用程序。从我们的目录中,在虚拟环境中,通过管理。
python manage.py startapp users
现在,我们应该拥有一个新应用程序的目录。让我们首先在该目录中创建与用户登录相对应的视图。 Django内置了用户登录的视图,但是这些不适合我们,因为我们需要自定义视图,这最好使用一个定义完成。
在此视图中,我们将首先检查发布请求,将请求传递到从django导入的登录名,对用户帐户进行身份验证,然后登录用户,然后再将其重定向到我们的feed应用程序。
在用户/views.py中,添加以下代码
username = request.POST['username'] # 从邮政请求获取用户名和密码
password = request.POST['password'] # 身份验证用户
这是基本登录视图所需的全部。现在,让我们通过扩展基本模板来为视图创建表单。首先,我们将为用户文件夹中的模板创建一个新目录。
mkdir users/templates
mkdir users/templates/users
现在,我们应该能够编辑用户/模板/用户/login.html。当我们使用时,我们将创建一个模板以允许用户注册。
nano users/templates/users/login.html
现在,在模板中,
这是登录模板的基础知识。它实际上就像结构上的另一个模板一样,但是在渲染时看起来有些不同。我们可以复制此代码以构建另一个非常相似的模板,称为regisher.html,我们将更改措辞并使用我们构建的新表单。让我们先制作模板。编辑用户/模板/users/register.html并添加以下代码:
现在,让我们为用户注册构建表单,然后在使用模型升级用户登录之前回到视图中。我们将从一开始就将此表格基本化,但将来纳入了更多详细信息和安全功能,例如协议和CAPTCHA。使用nano用户/forms.py编辑表单,并添加以下代码。
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']
因此,我们在这里有另一种形式,它起作用的很简单。这是带有用户名,电子邮件和密码以及确认密码字段的用户寄存器表单。请注意,此表单不会扩展常规表格。form类,它是模型表单,这意味着它具有元。一个字段的定义相同,类元标准定义了该表单对应于将写入表单的其余信息对应的模型。其中大部分已经存在于Django内置的UserCreationform中,因此我们将其用作类的基础(通过括号中)。
接下来,我们将检查注册用户的视图,因为我们有一个表单和模板。这是一个模态,就像新帖子视图中的一个一样。编辑用户/views.py并添加以下代码:
# …进口
这就是我们需要注册用户的全部,但是我们应该拥有更多信息。我们想知道用户注册的时间,网站上的最后时间,有关它们的一些信息,例如传记,时区等。另外,我们将需要更新我们的提要模型,发布,以说明用户模型并将帖子属于每个用户。为了做到这一点,我们将在两个应用程序中更新Models.py。让我们从编辑供稿模型开始。现在应该看起来像这样:
from django.db import models # …进口
author = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True, related_name='posts') # 加入此行
请注意添加到文件中的第二行。这是一个外键,将每个帖子归因于每个帖子的单个用户,因此我们可以确保我们以每个用户的使用者为基础保存帖子,并且在不归因于用户的情况下无法进行帖子。我们使用其代表的类定义此外键,删除参数,以确保帖子被用户,空和空白参数删除,以确保我们可以在必要时删除用户,并适应我们已经创建的帖子上的用户缺乏用户,以及一个相关名称,我们可以使用这些名称来引用用户创建的帖子。与Post.author的作者作者,此相关名称为我们发布了帖子本身的用户。现在,我们可以将帖子通过运行user.posts.all()或furs.posts.all()制作的用户。
现在,让我们的登录名更具弹性。我们已经可以通过简单地限制允许登录到网站的次数来使我们的网站易受网络钓鱼的影响,这很容易。在我们继续开发应用程序时,我们还开始在每个用户之前开始存储一些有关每个用户的信息。编辑用户/models.py,添加以下代码。
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='')
请注意,此模型与邮政模型相似。我们还有一个额外的导入时间,这将使我们能够在DateTime字段上设置默认值,并且我们还具有像帖子一样的角色feffield和Textfield。使用所有这些时间戳有助于我们保护网站并了解其使用,并且文本字段使我们在网站上渲染有关每个用户或作者的信息。 OneToOneField应该是唯一的次要考虑因素,其行为与Foreginkey完全相同,但每个后续模型只有一个。这样,用户只有一个配置文件,而他们可能有很多帖子。
现在,让我们改进登录名并注册视图以说明配置文件。首先,编辑用户/views.py并专注于寄存器视图:
# …进口
Profile.objects.create(user=user) # 确保添加此行,为用户创建配置文件
这只是为用户创建个人资料,而无需填写任何信息。现在,我们要确保不能频繁登录用户帐户,或者至少不能经常尝试密码,因此让我们更新登录视图。
# …进口
if user and user.profile.can_login < timezone.now(): # 请注意,我们现在检查用户是否可以登录
else: # 如果登录未成功,
user = User.objects.filter(username=username).first() # 这是我们更新用户配置文件的部分
profile.can_login = timezone.now() + datetime.timedelta(seconds=15) # 所以他们不能再登录几秒钟
这是安全的基本基础。确保该站点不容易受到某人的影响,只是尝试所有可能的密码组合,甚至同时尝试其中一些。这不会让知道自己的密码并在一些设备上登录的普通用户感到沮丧,但它会使众多的网络钓鱼机器人脱离应用程序。请注意,我们添加了一个带有变量can_login的IF语句,这应该是过去的时间,并使用相同的用户名使用每个失败的登录方式对其进行更新。这样,恶意用户将无法尽快猜测密码。 DateTime.timedelta()中的秒数也可以更新,并且该网站将更具弹性,但使用更多秒的时间稍微降低。我建议15开始。
请记住,我们构建了一个备份脚本来保存我们的工作,所以让我们继续备份到迄今为止我们拥有的一切,以确保我们保存了一切。运行命令:
sudo backup
再一次,这将为您的工作节省。我建议运行频繁的备份以保存您的工作,您甚至可能想自动运行备份作业。您可以使用称为Cron的Unix实用程序来执行此操作。要激活此实用程序,请运行以下命令并输入您的密码:
sudo crontab -e
如果您尚未为Nano选择选项1,则应该已经熟悉的文本编辑器,并使用箭头键滚动到文件底部。添加以下行:
0 * * * * sudo backup
Cron使用分钟,小时,每月,月,一周的一天, *或一个数字代表何时运行命令。使用0分钟, *在其余选项中 *,我们可以在分钟开始时每小时的第一分钟运行一个命令。这使我们可以自动备份代码。用sudo执行的所有作业作为root运行时,我们无需每小时输入密码。
为了使无需使用密码备份代码变得更容易,让我们禁用备份命令的密码。我们将通过执行以下命令并输入密码来做到这一点:
sudo visudo
现在,让我们滚动到文件的底部并添加另一行:
ALL ALL=NOPASSWD: /bin/backup
这使我们可以在没有密码的情况下运行命令"备份"作为任何用户。该格式很容易,只需将行的前缀" all = nopasswd:/bin/"和命令结尾,例如/usr/bin/bin/。
现在,让我们开始使用电子邮件。电子邮件对于网站确实很重要,因为这是一种使网站更安全,验证用户是真实的人,甚至向客户推销产品或服务的方法。许多经常互联网的人每天检查他们的电子邮件,并收到有关他们感兴趣的产品和服务的各种营销电子邮件。在启用Django网站上启用电子邮件时,有一些选择,欢迎您选择最适合您的电子邮件。
首先,您可以购买电子邮件服务,该电子邮件将使您可以从域中发送电子邮件并需要最少的代码。有许多服务提供此服务,例如Google Workspace,Sendinblue,Mailgun等。
否则,您将无法从头开始在服务器中构建自己的电子邮件服务。我建议使用此选项,即使它是更多的代码,可能需要特殊的托管。您将无法从家用计算机启动邮件服务器,因此,让我们继续检查配置和代码以在我们在云中启动服务器并在其中创建自己的邮件服务器之前,请发送电子邮件。
首先,使用以下命令编辑设置。PY:
nano app/settings.py
其中应用程序是您使用startApp创建的应用程序的名称。
添加以下行:
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)
确保在准备部署应用程序时更改这些更改,我们将在稍后重新访问。 email_address设置应为您要发送的电子邮件,并且应将密码(email_host_password)设置为您为服务器生成的密码。我将密码从配置文件加载,以使用以下逻辑将其排除在代码之外。
import os
import json
with open('/etc/config.json') as config_file:
config = json.load(config_file)
然后,我使用nano设置了一个使用config的JSON文件,如下所示。
编辑文件:
sudo nano /etc/config.json
添加以下行:
{
"EMAIL_HOST_PASSWORD": "<some password here>"
}
我们将继续编辑配置文件,并添加将在应用程序中使用的所有密码和密钥。现在,让我们快速研究如何使用Python发送电子邮件。首先,让我们为验证电子邮件创建模板,可以发送给用户,然后将其放入用户模板目录中。该模板将用HTML编写。
nano users/templates/users/verification_email.html
这封电子邮件很简单。它采用用户的上下文,网站的基本URL以及用于验证用户电子邮件的用户ID和令牌。在编写一些Python代码以渲染模板之前,请确保在设置中定义基本URL。继续,将以下行添加到app/settings.py的开始。
SITE_NAME = 'Django App'
PROTOCOL = 'https'
DOMAIN = 'example.com'
BASE_URL = PROTOCOL + '://' + DOMAIN
最终,当您的网站准备好上网并部署它时,您将需要将域名定义为您购买的域名以表示网站。这是您将在Navbar中输入的名称以访问您的网站。现在,您可以将域空白或占位符。您还需要将site_name更改为您要选择网站的名称。
在发送电子邮件之前,让我们创建一个令牌生成器,以便我们可以拥有一个永不过期的帐户激活令牌。我们可以通过构建和导入看起来如下的帐户激活令牌来做到这一点。编辑文件:
nano users/tokens.py
添加以下代码:
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()
该基本令牌生成器会生成令牌,我们可以将用户发送到URL中,用户可以用来验证其电子邮件并激活其帐户。
接下来,让我们看看如何发送电子邮件。使用Nano,编辑用户/email.py。
nano users/email.py
发送验证HTML电子邮件将看起来像这样:
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)
这很简单。我们导入发送电子邮件,使用模板和我们设置的电子邮件所需的功能,然后通过模板名称定义电子邮件,然后使用函数将其发送给用户。您会注意到我们尚未定义发送邮件的函数,send_html_email,所以让我们在已经添加到用户/email.py的代码下面写下此函数。
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()
这有点复杂,我们还没有准备好运行所有这些代码。请注意,我们定义了UNSUB_LINK,用户可以使用用户退订我们的电子邮件的链接。这很重要,因为用户将需要能够退出我们的电子邮件,除非他们想随时看到它们。我们还为我们的消息添加了文本替代方案,即HTML标签所剥离的HTML消息。最后,我们检查电子邮件是否发送,如果没有发送,我们在用户的个人资料中标记了他们的电子邮件无效。
让我们回到用户模型中,以便我们可以使所有工作都起作用。我们需要定义一个函数来生成链接以取消订阅,并定义一个布尔字段以标记用户的电子邮件无效。
首先,将以下导入添加到用户/型号的顶部。
nano users/models.py
# …
接下来,让我们将功能添加到用户模型中以制造令牌并检查用于激活电子邮件的令牌以及该字段,以保存用户是否成功接收其邮件。在用户/型号中,再次,将以下代码添加到模型末尾(缩进代码)
# …
TimestampSigner().unsign(key, max_age=60 * 60 * 24 * 30) # 有效期30天
这很简单,我们使用TimestAmpSigner(这是一种基本的加密工具)来创建一个令牌,该代币将在一定时间之后到期,并且我们还使用另一个功能来检查其是否有效。我们两次使用这些令牌,一次验证电子邮件,然后一次取消订阅链接。
现在我们已经拥有了这些,我们将要做的最后一项工作就是在视图中。在用户/views.py中,让我们添加视图以验证电子邮件地址并取消订阅。
nano users/views.py
首先,添加以下导入。我额外扔了几个,所以我们以后不必再进口更多物品了。
from .email import send_verification_email # 确保导入验证电子邮件发送功能
您可能已经有一些这些进口,但是重复它们并没有什么坏处。您将需要从用户导入验证电子邮件发送函数以及account_activation_token。
现在,在文件的底部,添加以下代码:
# 取消订阅
# 否则重定向到登录页面
# sendwelcomeemail(请求,用户)
这是很多代码。让我们分解。第一个功能,干净,简单,从邮件列表中取消订阅用户。第二个功能激活了他们的电子邮件,您会注意到我添加了评论功能,sendwelcomeemail。欢迎您使用电子邮件模板和功能定义发送欢迎电子邮件,我还没有。我投掷的最后一个功能很重要,因为激活电子邮件过期。因此,我们需要在某些时候重新发送激活电子邮件。我们可以为此使用基本表单,并致电该功能发送验证电子邮件。在执行此操作之前,让我们确保通过在寄存器视图中添加功能调用来确保它首先发送。在寄存器视图中的重定向之前,在用户/views.py中添加此行。
nano users/views.py
# …(之后)DEF寄存器(请求):
# …(之前)重定向(
您无需在该代码段中添加第一行和最后一行,只需确保寄存器视图将验证电子邮件发送给用户即可。看起来应该这样:
# …进口
send_verification_email(user) # 确保添加此行!
现在,我们需要添加一个表格来重新发送激活电子邮件。在用户/表格中。py,添加以下表格:
# …(进口)
我们还需要一个与此重新启动电子邮件激活表相对应的模板。让我们添加此模板。编辑文件:
nano users/templates/users/resend_activation.html
接下来,将以下代码添加到文件中。
哎呀,这很多!现在,当我们将代码部署到服务器时,我们将能够通过电子邮件单击发送HTML电子邮件并激活用户帐户。我们可能还想发送一封简单的欢迎电子邮件,所以让我们看看如何做到这一点。返回用户/email.py,添加以下代码:
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)
另外,我们将需要一个模板来渲染所有这些信息。在我的网站上,模板看起来像以下内容,但欢迎您随心所欲地格式化它。
请注意,我们没有关闭的身体或HTML标签,因为当我们添加HTML退订链接时,我们将其添加。这些很重要,但我们不想定义两次。
那接下来是什么?我们走了很长一段路。确实,我们应该准备将站点部署到服务器。我们可以添加@Login_Required Decorator,并确保我们的视图安全,进行用户注册,发送合规电子邮件和缓存信息,这是网站保持相关性所需要做的基础。我们将添加一些有用的功能,然后建立将代码部署到远程服务器,设置邮件服务器,域配置和过滤器以使我们的网站安全可靠的基础。
我们还需要密码重置视图,所以让我们非常快地添加。 Django的内置密码重置视图在某些功能中被打破,但是我们将研究如何编写自己的视图,电子邮件模板,表单和URL模式。这就是视图的样子,在用户/views.py中
# ...导入
此表单内置到Django,但是我们需要一个模板来确认密码重置,用户/templates/users/password_reset_confirm.html
我们还有一个模板来发送密码重置电子邮件,并使用简单的表单,用户/模板/users/passwork_reset.html发送密码。
电子邮件本身的模板很简单,它是一个基本的html文件,渲染链接以重置密码,在用户/模板/users/passwere_reset_email.html中。 Django将自动解释此文件。
我们还需要两个模板。首先是确认已发送电子邮件。这些视图已经在Django中,因此我们只需要在URLS.PY中解决它们。此模板位于用户/模板/用户/password_reset_done.html上
最后,要确认密码重置已完成,用户/模板/用户/password_reset_complete.html
现在,我们需要这些观点的URL模式。在用户/urls.py中,添加以下URL模式:
# ...以前的URL在这里
四个模板,很多!但是现在,我们一定能够从Web浏览器中随时随地重置用户的密码。
我了解这是很多代码。如果您的头部似乎有点远,那没关系。您将有所改善,理解将有所改善,并且您很快就会变得更加能够使用代码。如果您完全迷失了,我建议您在在线学习以学习为课程的自定进度后,稍后再回到此软件。这些通常可以免费入门,并会指导您回到这个项目时获得成功所需的一切。如果您觉得自己准备继续,请继续阅读,接下来,我们将介绍将代码部署到远程服务器并设置邮件服务器,并使用bash自动部署,以便您始终使用一些简单的命令来设置一个新项目。
在部署到远程服务器之前,我们需要做的最后一件事是使我们的网站更加安全。您会注意到登录视图仅采用用户名和密码,并且没有多因素身份验证或一个时间代码。这是一个简单的修复,并且使用相同的代码,我们可以使我们的网站发送短信,甚至可以响应发送给服务器的短信。首先,我们将返回用户模型,并添加一个将表示每个登录的时间戳签名者。我们还将在用户模型中添加一个唯一的旋转标识符,该标识符将用于为我们的登录添加额外的安全性。编辑用户模型,用户/型号。py,添加以下代码:
# 确保导入UUID,时间戳签名器和URL发电机(反向)
# 在这里添加此代码
# 并添加此功能
TimestampSigner().unsign(key, max_age=60 * settings.AUTH_VALID_MINUTES) # 有效3分钟
除了注释(与#的行上的代码)外,请确保您的用户/型号看起来像这样。打破这个,很简单。我们有一些导入器,一个时间戳签名器,它是一个加密实用程序,可以生成安全的代码并进行验证,以确保其有效,仅使用一次,而不是比一定数量的秒更古老。我们还使用UUID,这是一个唯一的标识符,可以在令牌的签名中标识我们的用户,以及在将令牌发送给用户的URL中。我们将使用此基本密码学来构建两个因素身份验证视图。在我们做其他任何事情之前,让我们运行迁移,以便更新我们的用户模型。在带有manage.py的目录中,运行以下命令以进行和完成迁移。
source venv/bin/activate
python manage.py makemigrations && python manage.py migrate
这很重要,因为每次我们对模型进行更改时,我们都需要创建表并使用默认值更新数据库,然后才能实际使用模型。
接下来,让我们即兴创作登录视图,以重定向到辅助身份验证视图。在用户/views.py中,删除登录功能并将其重定向到我们在用户模型中生成的URL。
# …进口
if user and user.profile.can_login < timezone.now(): # 请注意,我们现在检查用户是否可以登录
# 删除此处的auth_login函数
return redirect(user.profile.create_auth_url()) # 注意我们在这里重定向到新的URL
else: # 如果用户不使用多因素身份验证,请将其记录在其中。
else: # 如果登录未成功,
user = User.objects.filter(username=username).first() # 这是我们更新用户配置文件的部分
profile.can_login = timezone.now() + datetime.timedelta(seconds=15) # 所以他们不能再登录几秒钟
因此,这很简单,现在我们可以在创建它时将其重定向到两个因素身份验证视图。如果用户尚未添加电话号码,我们也有回退。我们将添加一个基本视图,以尽快添加电话号码并尽快登录短信。
首先,我们需要一种简单的方法来从我们的代码发送短信。为此,我们可以从许多API中进行选择,但我认为最简单的是Twilio。他们还为较小的项目提供了良好的定价,以及大量折扣。在twilio.com上创建一个帐户,填写有关项目的一些详细信息,购买电话号码,然后将API键复制到您的设置。然后,在新文件(用户/sms.py)下添加此代码。
nano users/sms.py
# 导入所有必要的软件包
# 此代码与Twilio一起发送文本
# 辅助功能可以获得一个数字如此多的数字
# 发送文本以验证用户
# 向用户发送此功能的任何文本
# 使用此功能验证代码
# 验证时间
确保适当地更改设置,并使用键添加这些行:
# 确保从您的Twilio仪表板复制这些
AUTH_VALID_MINUTES = 3 # TFA页面有效的分钟数一旦实例化
首先,我们将需要我们的两个因素身份验证视图的表格。编辑用户/forms.py,添加以下代码。
# …进口
# 输入我们电话号码的表格
# 认证的形式
接下来,让我们在用户/views.py中创建视图
# …进口
我们还需要这两种观点的模板。让我们先添加MFA模板。
nano users/templates/users/mfa.html
将此HTML代码添加到模板
这是非常自我解释的。表格发送代码或空代码,如果我们收到空代码,您会在视图中注意到我们发送代码。然后,我们只有两个提交按钮,这样我们就可以使用任何一个按钮发送代码。接下来,我们将添加一个简单的表格来添加电话号码。
nano users/templates/users/mfa_onboarding.html
添加以下HTML:
此表单要简单得多,它只是呈现我们创建的电话号码表单,并让用户添加电话号码。
这看起来真的很好!只要一切都正确设置,我们就应该能够发送消息,并在添加URL模式后立即将用户登录。我们需要设置的最后一件事是配置文件视图,因此我们可以确保用户可以更改其电话号码而不会登录。此外,我们最终将要添加一个"停止戒烟"选项,因此用户可以短信"停止"以选择未来的文本消息。
让我们将配置文件视图添加到用户/views.py。此视图将更新用户的简历,电子邮件,用户名和电话号码,并允许我们启用多因素身份验证。首先,我们将需要另外两种表格/形式。
# ...导入
接下来,我们可以创建一个视图以使用这两种形式。编辑用户/views.py并添加视图。
# 添加这些导入
我们还需要此视图的模板。
nano users/templates/users/profile.html
您会注意到这是一个相当简单的表单,但是其中包含一些JavaScript,它们会在更新时自动发布表单的内容。这对拥有很有用,因此您可以进行编辑而无需每次提交。
接下来,我们需要在用户URL模式中代表所有这些视图的URL。编辑用户/urls.py并添加此代码:
# …以前的代码,导入
# …我们先前输入的URL模式,添加接下来的三行
现在是测试我们项目的好时机。但是首先,让我们再运行另一个备份。
backup
并运行服务器。在我们部署到Linux服务器之前,最好在帐户上启用两个因素身份验证。我们将执行此操作,将其转到我们的个人资料URL,/用户/个人资料/,并在输入我们的电话号码后检查框以启用身份验证,然后提交表格。
python manage.py runserver localhost:8000
访问您的网页访问您的Web浏览器,我在此示例中使用Google Chrome,然后输入url https:// localhost:8000/eaccement/profile/profile/profile/
如有必要,您将能够登录并启用两个因素身份验证。
该项目需要服务器运行,因此它可以真正发送邮件。但是首先,我们需要一种查看错误的方法。您会注意到,如果您在调试模式下运行服务器,则使用设置。DEBUG等于true,则服务器会自动显示错误。为了在不使用调试模式的情况下显示错误,该模式在生产服务器上是不安全的,我们应该为其添加视图。我们需要处理的最重要的错误是:
错误500-我们代码的问题 错误404-找不到的页面(损坏的URL) 错误403-允许拒绝错误
让我们添加一个新应用程序来处理这些错误,称为错误。
python manage.py startapp errors
像以前一样,将其添加到settings.py中,在installed_apps设置中,然后从app/urls.py中的某些视图中添加引用,其中应用程序是您的django项目的名称。
handler404 = 'errors.views.handler404'
handler500 = 'errors.views.handler500'
handler403 = 'errors.views.handler403'
除了错误视图,模板和一些中间件之外,我们还需要这一切。让我们将其定义为:
# 在这里创建您的观点。
接下来,让我们定义中间件来处理这些错误。我们将首先以中间件的名称添加到settings.py中的middleware_classes来做到这一点。
# ...以前的中间件
接下来,让我们添加中间件。
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.')
我们添加了一个函数来通过使用螺纹本地螺纹来获取当前异常,这有助于我们跟踪代码中的任何错误。就模板而言,我们只需要一个,因为我们在视图中动态定义标题。该模板只需要渲染标题和"跟踪",即我们从上下文中的错误追溯。
nano errors/templates/errors/error.html
这是我们迄今为止最简单的模板,但这很容易看到我们项目中的错误。接下来,让我们在设置中禁用调试。
nano app/settings.py
找到将其设置为true的行,然后将其更改为false
DEBUG = False
继续并立即备份该应用程序。我们准备部署到远程Linux服务器,并继续添加功能。
sudo backup
在将此代码发布到服务器之前,我们应该考虑代码可能存在一些问题。根据案例,接受发布给他们的信息的网站将在发布垃圾邮件和删除垃圾邮件的困难方面存在问题。这不应该立即发生,但是如果发生这种情况,我们稍后将研究如何自动在网站上自动垃圾邮件,并使机器人更难访问站点,以及如何停用用户帐户,并通过使用ID或生物识别扫描(例如指纹或面部识别)来验证用户的身份。
查看我们检查的多因素身份验证示例,在生产中,情况可能会有所不同。请注意,我们是如何限制登录和到期令牌的。如果机器人正在访问站点,则两个因素身份验证可能会更加困难,因为它们可能同时输入代码。为了解决这个问题,让我们在用户模型中使用模型,并在使用多因素身份验证和电话号码进行身份验证时声明我们如何与站点进行交互。我们还将添加一个通过电子邮件进行身份验证的选项。首先使用Nano编辑用户模型。
nano users/models.py
这就是我们要添加的模型的外观。我们不需要任何方法,只是变量来存储ID,用户,时间戳,有效期,长度以及对任何多因素身份验证的尝试(发送到电话或电子邮件的123456之类的代码)。
# 一个用于登录网站的基本令牌
我们还向用户添加特权,我们现在将手动设置它,然后最终迁移到自动招募特权用户。在用户模型中,在配置文件中添加此行:
vendor = models.BooleanField(default=False)
与数据库的任何更改一样,我们需要在Django中编辑Models.py文件时进行迁移并迁移数据库。请记住,要做到这一点,我们首先使用源(如果终端开放以来还没有使用)然后python manage.py进行迁移和迁移。
cd project-directory-you-named # (如果需要)
目前,您可以使用Shell来招募您作为供应商创建的任何帐户。
python manage.py shell
from users.models import Profile
p = Profile.objects.get(user__username='Charlotte')
p.vendor = True
p.save()
exit()
现在,让我们进化我们的多因素身份验证视图以使用此令牌。首先,我们需要修改MFA助手实用程序。使用Nano,
nano users/mfa.py
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
# 使用其电子邮件或电话号码对用户进行身份验证
token = MFAToken.objects.filter(uid=username, expires__gt=timezone.now() + datetime.timedelta(seconds=30)).order_by('-timestamp').last() # 通过在URL中传递的值过滤令牌(uuid)
if not token: token = MFAToken.objects.create(user=User.objects.filter(profile__uuid=username).first(), uid=username, expires=timezone.now() + datetime.timedelta(seconds=115)) # 如果没有创建此会话,请创建它
user = User.objects.filter(id=token.user.id).first() # 从令牌中获取用户
if not user and request.user.is_authenticated: return redirect(reverse('feed:home')) # 如果它们已经被认证,请将其记录在中
if not user: raise PermissionDenied() # 否认是否没有找到用户
if not user.profile.enable_two_factor_authentication and user.is_active and user.profile.check_auth_token(usertoken, token): # 检查验证令牌
auth_login(request, user, backend='django.contrib.auth.backends.ModelBackend') # 登录用户,如果尚未登录
user.profile.mfa_expires = timezone.now() + datetime.timedelta(minutes=settings.LOGIN_VALID_MINUTES) # 在其多因素身份验证上设置有效期
return HttpResponseRedirect(next if next != '' else reverse('landing:landing')) # 将用户重定向到下一页
if not user.profile.mfa_enabled: # 检查是否启用了MFA
if not check_verification_time(user, token): # 检查时间
user.profile.mfa_enabled = False # 清除电话号码
user.profile.enable_two_factor_authentication = True # 启用MFA
user.profile.phone_number = '+1' # 禁用电话号码
user.profile.save() # 保存个人资料
auth_login(request, user, backend='django.contrib.auth.backends.ModelBackend') # 如果未启用其MFA,请记录用户
if request.method == 'POST' and not fraud_detect(request, True): # 如果请求是邮政请求
form = TfaForm(request.POST) # 实例化表格
code = str(form.data.get('code', None)) # 获取代码
if code and code != '' and code != None: # 确保它不是空的
token_validated = user.profile.check_auth_token(usertoken) # 检查验证令牌
is_verified = check_verification_code(user, token, code) # 检查代码
if token_validated: # 如果一切
if is_verified: # 是有序的
user.profile.mfa_enabled = True # 启用MFA(如果尚未启用)
auth_login(request, user, backend='django.contrib.auth.backends.ModelBackend') # 登录用户
for key, value in request.GET.items(): # 为下一个参数构建Querystring(如果有)
return HttpResponseRedirect(next) # 重定向
elif not token_validated: # 如果令牌无效
if p.mfa_attempts > 3: # 如果尝试太多
if form.data.get('send_email', False): # 发送电子邮件(或文字)
# 渲染表格(用于获取请求)
当我们添加此代码时,请确保导入该函数以发送电子邮件。在文件的顶部,用户视图(带有其他导入),添加
from .mfa import send_verification_email as send_mfa_verification_email
现在,我们需要在任何一个都起作用之前编写该功能。它应该扩展我们的发送电子邮件功能,并只需通过验证代码将电子邮件发送给用户。
nano users/mfa.py
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))
因此,这一切都很好,现在我们有了一个多因素身份验证系统,该系统取决于电话号码或电子邮件登录。但是,我们还需要一种删除或至少隐藏不符合我们条款的用户的方法。这些可能是垃圾邮件发送者,机器人或任何对我们工作不好的人。看看我在网站上监视用户的视图:
# 进口
from .tests import is_superuser_or_vendor # 我们需要创建此测试
# 获取用户列表
return render(request, 'users/users.html', { # 在模板中返回用户
请注意,此代码使用测试,我们需要在tests.py文件中声明此测试并导入它。编辑用户/tests.py,让我们创建测试。
def is_superuser_or_vendor(user):
return user.profile.vendor or user.is_superuser
这与用户/用户一起结合使用。html模板,看起来像这样:
请注意,该模板包含另一个模板,用户/user.html。当使用具有子测试且不使用扩展的模板时,添加下划线的好主意()在文件的名称扩展之前,以区分模板。
请注意,这是很多Jinja,您可能没有定义所有这些变量。但这就是我的代码的样子。
<small># {{user.id}} </small>
我们还需要另一个子板toggle_active.html。该模板应是一种使我们可以切换用户是否处于活动状态的表单。
我们还需要添加视图以切换用户活动和适当的URL模式。当我们使用它时,让我们添加一个视图以删除用户,以防我们需要。
# 进口
success_url = '/' # 成功URL的重定向
def test_func(self): # 测试用户是否是超级用户,并且有权删除
尽管在必要时是实用的,但在大多数情况下,删除用户不应是必要的,但如果需要解散,我们可以切换访问网站的用户的可见性。
我们添加的URL模式看起来像这样。使用Nano,编辑用户/urls.py并添加以下行:
nano users/urls.py
这些行应在用户视图中的路径列表中,在结束"]"之前,但是在开始之后" ["。
# …
# …
现在,请确保备份网站,以便您可以在我们将继续进行的Web服务器上下载它。从命令行,
sudo backup
现在我们的网站已备份。
因此,现在我们有了一些有用的功能。但是这里的大局呢?该代码仍然无法从Internet访问,我们还没有邮件服务器,我们需要扩展应用程序以包括全面的验证过程以及平稳的布局,以帮助我们探索该站点,以及用于认证特权用户的安全协议。
我们将解决这一切。目前,最重要的事情就是在线获得此代码,我们只能在Ubuntu Server上使用几行BASH来进行。不过,您需要为此租用服务器,除非您在家中有服务器和允许您打开端口的业务互联网订阅。我亲自在安装在公寓中的HP Z440上运行我的网站,但通常需要便宜得多的基本租用虚拟专用服务器(VPS)。
请记住,我们现在正在运行的代码相对较薄,在我们准备好使用所需的产品来构建产品之前,它需要维护和改进。确保小心使用Internet的工作,请确保您是否在Linux服务器上公开部署此网站,您有计划阻止与网站的不必要的互动。一开始这可能不会是问题,但是我们将研究各种解决方案来打击这一问题,包括机器学习,人工智能和计算机视觉。当它确实成为问题时,请在本文中进一步寻找解决方案。
在租用VP的方面,您可以去很多地方。 Google Cloud拥有VPS服务器,Ionos,Kamatera,Amazon AWS和更多提供商提供适合我们需求的云服务器解决方案。
您需要单击他们的表格,然后选择一个计划才能开始。您可以与任何提供商一起使用基本计划,但是请确保提供商允许您打开端口邮件服务器端口发送电子邮件(这应该是端口587和端口25),一些提供商会阻止这些端口。到目前为止,我在Ionos和Kamatera方面拥有最好的经验,它们都可以让我发送无限的电子邮件,并且它们的价格非常便宜。
您将通过称为SSH或Secure Shell的协议连接到新服务器,该协议使您可以像个人计算机一样与服务器远程接口。设置服务器时,托管提供商可能会要求您添加SSH键,否则它们会为您提供用户名和密码。 SSH键是您将如何从命令行登录到服务器以编辑代码。使用以下SSH-键选项生成SSH键。
ssh-keygen
保存文件并覆盖该文件,如果还没有,请旋转SSH键是很好的。现在,您可以使用以下命令查看SSH键。您将需要将其复制到远程服务器,以便可以使用它来验证。
cat ~/.ssh/id_rsa.pub
如果您在键入该命令时看不到SSH键(以" SSH-RSA AAA"开头的长数字和字母字符串),请尝试生成RSA键(它们更安全,因此我建议使用它们。)以下代码将生成4096位RSA SSH键。
ssh-keygen -t rsa -b 4096
创建一个运行Ubuntu的VPS,但是您打算这样做。通过单击提供者网站上的表单(kamatera.com,ionos.com或类似)上的表单来创建VP,您将要登录。要执行此操作,请使用SSH命令使用IP地址(看起来像xx.xx.xx.xx.xx的地址)。您还需要对我们创建的服务器上的默认用户名敏感,例如Ubuntu。
ssh ubuntu@XX.XX.XX.XX
可能会要求您提供密码,如果要求您输入密码,请输入。我们不会使用默认用户名,因此让我们首先创建新用户并在其帐户中添加SSH键。
让我们开始添加一个新的SSHD_CONFIG文件,该文件告诉服务器如何使用SSH。
nano sshd_config
# 这是SSHD服务器系统范围的配置文件。 看
# SSHD_CONFIG(5)以获取更多信息。
# 此SSHD与路径=/usr/local/sbin:/usr/locar/bin:/usr/sbin:/usr/bin:/sbin:/sbin:/bin:/usr/usr/gash
# 默认sshd_config中选项的策略
# OpenSSH将用其默认值指定选项
# 可能,但让他们发表评论。 未注册的选项覆盖
# 默认值。
# 港口22
# 地址
# 听听0.0.0.0
# 听听::
# hostkey/etc/ssh/ssh_host_rsa_key
# hostkey/etc/ssh/ssh_host_ecdsa_key
# HOSTKEY/ETC/SSH/SSH_HOST_ED25519_KEY
# 密码和关键
# rekeylimit默认没有
# 记录
# syslogfacity auth
# loglevel信息
# 验证:
# LogingRaceTime 2m
# 允许Rootlogin禁止使用
# 严格模具是
# Maxauthtries 6
# 最大值10
# 期望.ssh/授权_keys2将来默认情况下会被忽略。
# 授权principalsfile无
# 授权keyscommand无
# 授权keyscommanduser没人
# 为此,您还需要/etc/ssh/ssh_known_host中的主机键
# hostbasedAuthentication no
# 如果您不信任〜/.ssh/nown_hosts,则更改为"是"
# hostbasedAuthentication
# 忽略了众议员霍斯特斯
# 不要读取用户的〜/.rhosts和〜/.shost文件
# 无知的主机是
# 要禁用隧道清晰的文本密码,请在此处更改!
# PliperEmptypasswords no
# 更改为"是"以启用挑战响应密码(当心问题
# 一些PAM模块和线程)
# Kerberos选项
# Kerberosauthentication
# Kerberosorlocalpasswd是的
# KerberosticketCleanup是的
# kerberosgetafstoken
# GSSAPI选项
# GSSAPIATHENTICATION NO
# gssapicleanupcredentials是的
# GSSAPISTRICTACCEPTORCHECK是的
# gssapikeyexchange no
# 将其设置为"是"以启用PAM身份验证,帐户处理,
# 和会话处理。如果启用了,PAM身份验证将
# 可以通过KBDInteractiveAthentication和
# 密码授权。 根据您的PAM配置,
# 通过KBDInteractiveAthentication进行的PAM身份验证可能绕过
# 设置"没有通信的允许原始斑块"。
# 如果您只希望PAM帐户和会话检查即可运行
# PAM身份验证,然后启用此验证,但设置密码授权
# 和kbdInteractiveAthentication至" no"。
# 是的
# 允许forwarding是的
# Gatewayports no
# X11DISPLAYOFFSET 10
# x11uselocalhost是的
# 是的
# printlastlog是
# tcpkeepalive是的
# 许可证环境号
# 压缩延迟
# 客户端Interval 0
# 客户端Alivecountmax 3
# 二手
# pidfile /run/sshd.pid
# Maxstartups 10:30:100
# 通知号号
# chrootdirectory无
# 版本addendum无
# 没有默认横幅路径
# 允许客户通过环境环境变量
# 覆盖无子系统的默认值
# 以每个用户为基础的覆盖设置的示例
# 匹配用户anoncvs
# x11福尔德编号
# 允许Forwarding no
# 许可证号
# forcecommand cvs服务器
请记住,Ctrl+X和Y保存文件。接下来,让我们编写一个名为initialize的基本脚本(所有用户的默认主目录中)。
nano initialize
将这些行添加到文件中,更换
# !/bin/bash
要引导您浏览此文件,让我们逐行开始。第一行告诉编译器这是一个bash脚本。然后,我们正在安装依赖项,将sshd_config复制到正确的目录,重新启动SSH,为root生成SSH键,添加用户'team'(您可以为此选择一个名称,请使用带有其名称和禁用密码的Adduser命令)。我们还将团队添加到Sudo Group,生成他们的SSH密钥,还将我们的钥匙添加到授权密钥和他们的钥匙中,然后打印其钥匙。这个新用户将是我们登录网站的方式。
在新的终端中,继续并再次打开服务器。
ssh team@XX.XX.XX.XX
这次您不需要密码,因为您有一个SSH键。我们还禁用使用密码登录,以使网站更安全。
现在,该服务器完全空白,没有任何信息。让我们从GIT将项目克隆起来,以便我们可以在远程计算机上下载并运行它。在通过SSH连接的远程服务器上,首先打印您的SSH键:
cat ~/.ssh/id_rsa.pub
接下来,将此键粘贴到GIT设置中,就像我们之前设置GIT存储库一样。现在,我们可以将项目直接克隆到服务器。确保您首先在本地备份了该项目,以便在GIT服务器上下载。
git clone git://github.com/you/yourproject.git
完美的。现在所有文件都在这里。我们可以用LS看到它们
ls
现在,让我们开始设置服务器。首先,将您的项目目录复制到我们将用于该项目的简单,令人难忘的名称。
cp -r yourproject whatyoucalledit
" WhatYoucalledit"是您项目的新名称。接下来,我们需要构建一个基本实用程序来设置服务器。我们将保存该公用事业,并将来使用它。要构建此实用程序,让我们创建一个用户二进制文件以定义我们如何编辑脚本。使用bash,编辑/usr/bin/ascript
sudo nano /usr/bin/ascript
确保在那里使用sudo,以便您可以权限编辑文件。在文件中,添加以下行:
# !/bin/bash
echo "# !/bin/bash" >>/usr/bin/$ 1
请记住,此脚本以参数为脚本名称为$ 1。首先,它检查文件是否存在或以其他方式创建该文件,添加了以声明脚本的第一行是bash,更改其权限,对其进行编辑,并将其名称添加到 /etc /ascripts中,使我们可以存储我们创建的脚本的名称。如果文件已经存在,只需更改权限并将其编辑。保存文件,接下来我们将更改其权限。只要我们使用此脚本,我们就不必再这样做了。
sudo chmod a+x /usr/bin/ascript
完美的。现在,让我们创建一个称为设置的脚本。首先,不要让您不知所措,而是看看我的设置脚本的样子。我们将介绍该脚本在您的项目中的外观,您将不需要我脚本中的所有内容。
# !/bin/bash
# sudo chmod a+x脚本/usersetup
# ./scripts/usersetup
# ssh-keygen
# 项目目录
# 日志命令
# 纳米配置
# git config
# 更新并安装
# 启用Clamav防病毒软件
# 设置主机名
# 设置Postgres
# 设置数据库备份
# 禁用iPtables
# 安装BitDefender
# 设置后缀
# 创建DIRS
# 设置Virtualenv
# 获得并建立依赖性
# 设置防火墙规则
# 安装PYPI依赖性
pip3 install --upgrade opencv-python # == 4.5.4.60
pip3 install --upgrade opencv-contrib-python # == 4.5.4.60
# PIP安装OpenCV-Python == 4.5.5.64
# PIP安装OpenCV-Contrib-Python == 4.5.5.64
# 安装certbot
# 运行certbot
# 重新加载邮件服务器
# 复制证书
# sudo cp /etc/letsencrypt/live/femmebabe.com/privkey.pem privkey.pem
# sudo cp /etc/letsencrypt/live/femmebabe.com/cert.pem cert.pem
# 补丁VENV
# 设置用户设置
# 设置权限
# sudo chown -r团队:用户/var/run/
# sudo chown root:root/run/sudo/ts -r
# sudo chmod 664 db.sqlite3
# sudo chown www-data:用户db.sqlite3
# 复制配置并设置权限
# 设置数据库
# 注入PAM配置并删除错误的SSH配置
# sudo sed -i''''$ d'/etc/pam.d/sshd
# sudo sed -i''''$ d' /etc /profile
# 复制bin脚本并设置权限
# 重新加载和启用服务
# 启用Apache模块
# sudo a2dismod mpm_event
# sudo a2dismod mpm_worker
# sudo a2enmod mpm_prefork
# 禁用默认网站
# 启用我们的网站
# 重新加载守护程序和重新启动Apache,Postfix和Opendkim
# 设置权限
# 交换配置
# 初始化标题引擎
# 设置git
# 显示IPv6和OpendKim用于域配置
# 设置完成
那是很多设置!简而言之,该代码记录命令,配置纳米和git,通过文件复制,下载和安装Ubuntu Apt软件包,Python依赖关系,配置后缀,配置后缀,配置PostgreSQL(数据库服务器)(数据库服务器)并加载数据库并配置UFW(不复杂的firewall),使依赖依赖依赖依赖,依赖依赖性,依赖依赖,置于依赖性,置于依赖性,置于依赖性,置于依赖性,置于依赖性,置于依据,置于依据,并设置服务器,安装配置,启动和启用dever,分配交换,设置权限并打印IP,IPv6地址和OpenDKIM密钥。相当简单,但看起来很多代码。我们不需要很多,因为我们没有依赖关系,我们不使用芹菜,芹菜或达芙妮,但是无论如何我们都会安装其中的一些来开始。请注意,此代码已声明了几次域。
我们还需要购买一个域名(这是每年的少量费用)。我建议Squarespace用于购买域,它们的布局是直观且易于使用的。您可以购买自己选择的任何域,但是在此示例中,我使用的是femmebabe.com。购买域后,请前往Squarespace DNS配置面板,并通过IP地址添加将您的域指向服务器的A记录。看起来应该这样:
@ a xx.xx.xx.xx
将 @运算符作为主机,这意味着该域下的所有子域和根域都将重定向到服务器。还有更多的记录要声明,但是一旦我们准备发送邮件,我们就可以继续进行这些记录。请记住,您可能需要几天才能成功从服务器发送邮件。我们设置的DNS记录将需要时间进行传播。
无论如何,我们唯一需要开始的记录是A记录。因此,现在我们可以根据项目填写以下脚本并运行它。
让我们从一个较小的设置脚本开始,只需安装我们需要的基本进度所需的内容即可。我们还不使用太多的依赖项或PostgreSQL,我们将只启动基本的HTTP服务器,并在完成后担心认证。请记住,要获得HTTPS证书并安全运行服务器,我们将需要购买域名以及租金服务器。现在,用您的项目目录中的用户名称" DIR"替换此文件中的"团队",并在<>标签中提供电子邮件和域。
此外,在运行此代码之前,我们需要将设置更改为防火墙托管提供商支持(如果有)。通常,这是在您的托管提供商的"网络"选项卡中,或者如果您是自托管,则在路由器的"端口转发"部分中。如果您使用的是自托管,您还需要通过服务器计算机的地址通过路由器设置静态IP。您将需要打开以下端口以进行读/写访问。
22(SSH) 25(邮件) 587(邮件) 110(邮件客户端) 80(http) 443(https)
# !/bin/bash
# 日志命令
# 纳米配置
# git config
# 更新并安装
# 启用Clamav防病毒软件
# 设置主机名
# 设置数据库备份
# 禁用iPtables
# 设置Virtualenv
# 安装certbot
# 运行certbot
# 设置用户设置
# 设置权限
# sudo chown -r团队:用户/var/run/
# sudo chown root:root/run/sudo/ts -r
# 重新加载和启用服务
# 启用Apache模块
# 重新加载守护程序和重新启动Apache,Postfix和Opendkim
# 显示IPv6和OpendKim用于域配置
在运行此代码之前,请确保您购买的域已连接到服务器。为此,请在本地计算机上打开一个终端,然后使用您的域运行此命令:
ping femmebabe.com # ping之后,在此处插入您的域
如果所有人看起来都很好并且服务器正在发送响应,那么我们准备运行脚本并安装软件包以及启动,启用和认证我们的Apache服务器。
这不是配置PostFix所需的所有设置,我们将稍后再查看该设置。现在,运行此设置代码,需要花费几分钟的时间才能安装和证明您的服务器。再次,请确保根据您购买的名称在脚本中替换名称,电子邮件和域名。
现在已经配置了服务器,您可以在任何Web浏览器中转到URL并检查服务器正在运行HTTPS。如果不是这样,请尝试等待一会儿DNS记录赶上来,然后运行以下命令重试证书认证:
sudo certbot --apache --non-interactive --agree-tos --domains <domain>.com --email <youremail>@gmail.com
只要您正确配置了所有内容,就应该能够访问Apache的默认页面,以了解您的代码正在工作并显示实时网页。接下来,让我们编辑设置。py以将我们的默认调试模式更改为生产。我们还将在设置以及内部IPS中配置域。
nano yourproject/settings.py
在设置中,更改/添加这些行。
# 站点配置
现在,我们需要配置Apache2。让我们编辑配置文件,我们将使用此行部署:
sudo nano /etc/apache2/sites-available/femmebabe-le-ssl.conf
此配置文件中应包含我们的域名,以及用户和项目的名称。我正在使用域名femmebabe.com,用户名团队和项目名称femmebabe。
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>
在配置服务器时,请确保在此示例代码中替换项目的名称,目录和域的名称。现在,我们需要禁用默认网站。这可以使用bash完成。
sudo a2dissite 000-default-le-ssl
sudo a2dissite 000-default
sudo a2dissite default-ssl
接下来,我们也可以使用bash启用默认网站和Reload Apache2。请记住,在/etc/apache2/stite-bailable/budable/insed ins efemmebabe用您声明的文件的名称替换。
sudo a2ensite femmebabe-le-ssl
sudo systemctl reload apache2
返回您在Navbar中的域。您应该在Web浏览器中查看您配置的网站。恭喜!如果您看不到它,则可能需要进行一些更改。仔细查看项目中的设置,Apache配置,并确保您没有任何错误,并运行以下命令以检查项目是否错误。
cd projectname
source venv/bin/activate
python manage.py check
如果您的Python项目中有错误,请将其追踪到它们所在的位置并修复它们。您可能无法根据它们的位置看到所有错误,因此,如果您有一个简单地说"填充不是重新进入的错误"的错误,请在虚拟环境中编辑以下文件,注册表。Py,以暴露该错误。
nano venv/lib/python3.12/site-packages/django/apps/registry.py
滚动到第83行,在此增加了此运行时错误(提高RuntimeRoror(" populate()不重入"),然后在此行之前添加注释,然后在相同的凹痕中添加Self.App_Configs = {}。看起来像这样:
# 防止重新进入电话,以避免运行AppConfig.ready()
# 方法两次。
# 提高RuntimeRor(" pupulate()不是重入")
然后,您可以再次检查项目并暴露错误。
python manage.py check
然后,您可以看到错误并修复它。将其修复并没有错误编译时,请确保将文件重新更改为这样,这样看起来像这样:
# 防止重新进入电话,以避免运行AppConfig.ready()
# 方法两次。
# self.app_configs = {}
如果服务器在线,当我们对其进行进一步的更改时,我们需要使用以下命令重新加载服务器:
sudo systemctl reload apache2
惊人的!但是发送邮件呢?要开始发送电子邮件,我们首先需要更新域配置。这应该在Squarespace的DNS面板中,或您选择的任何域名注册商。我们还需要安装和添加配置,并运行一些命令。
首先,让我们获取服务器的IPv6地址。然后,我们将打开您的DNS并添加记录。
要获取服务器的IPv6地址,请使用此命令:
ip -6 addr
现在,我们可以将以下记录添加到DNS设置中。我的记录看起来像这样。但是,对于您的记录,您应该用IP替换IP地址(不是75.147.182.214,这是我的)。另外,添加您的域,代替femmebabe.com,以及在上一个命令中找到的IPv6地址(您无法使用Mine,Fe80 :: 725a:FFF:FFF:FE49:3E02)。不用担心域名目前,当我们使用OpendKim设置Postfix,Mail Server,并打印键时,这是创建的。我们将进行最后一个配置。
@ 一个 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:fff:fe49:3e02〜
default._bimi TXT N/A。 v = bimi1; l = https://femmebabe.com/media/static/femmebabe.svg
_dmarc TXT N/A。 v = dmarc1; p =无
sendonly._domainkey
TXT
N/A。
现在,我们需要为Postfix添加一些持久的配置。我们需要做的就是确保用您使用的域名替换域名femmebabe.com。让我们一一查看所有配置文件,然后将它们安装在我们项目中称为Config的目录中,以安装到OS。
nano config/etc_postfix_main.cf
将此文本添加到文件中
# 请参阅/usr/share/postfix/main.cf.dist,以获取评论,更完整的版本
# debian特定:指定文件名将导致第一个
# 该文件的行用作名称。 Debian默认
# IS /etc /mailname。
# Myorigin = /etc /mailname
# 附加域是MUA的工作。
# 输入下一行,以生成"延迟邮件"警告
# delay_warning_time = 4H
# 请参阅http://www.postfix.org/compatibility_readme.html-默认为3.6 on
# 新的安装。
# TLS参数
# 小米配置
下一个配置!
nano config/etc_postfix_master.cf
添加以下行:
#
# Postfix Master Process配置文件。 有关格式的详细信息
# 在文件中,请参阅主(5)手册页(命令:" Man 5 Master"或
# 在线:http://www.postfix.org/master.5.html)。
#
# 编辑此文件后,不要忘记执行" Postfix Reload"。
#
# ====================================================================================
# 服务类型私人UNPRIV CHROOT WAKEUP MAXPROC命令 + ARGS
# (是)(是)(否)(从不)(100)
# ====================================================================================
# smtp inet n -y -1后屏幕
# SMTPD PASS - Y-- SMTPD
# DNSBlog Unix-- Y -0 DNSBlog
# tlsproxy unix-- y -0 tlsproxy
# 选择一个:仅对环回客户端或任何客户端启用提交。
# 127.0.0.1:ubmission inet n -y-- smtpd
# -O syslog_name = PostFix/提交
# -o smtpd_tls_security_level = gentrypt
# -o smtpd_sasl_auth_enable = yes
# -o smtpd_tls_auth_only =是
# -o smtpd_reject_unlisted_recipient = no
# -o smtpd_client_resterrictions = $ mua_client_resterrictions
# -O smtpd_helo_resterrictions = $ mua_helo_restrictions
# -o smtpd_sender_resterrictions = $ MUA_SENDER_RESTRICTIONS
# -o smtpd_recipient_resterrictions =
# -o smtpd_relay_resterrictions = pull_sasl_authenticated,拒绝
# -o milter_macro_daemon_name =始发
# 选择一个:仅适用于回环客户端或任何客户端的SMTP。
# 127.0.0.1:smtps inet n -y-- smtpd
# smtps inet n -y-- smtpd
# -O syslog_name = Postfix/smtps
# -O smtpd_tls_wrappermode = yes
# -o smtpd_sasl_auth_enable = yes
# -o smtpd_reject_unlisted_recipient = no
# -o smtpd_client_resterrictions = $ mua_client_resterrictions
# -O smtpd_helo_resterrictions = $ mua_helo_restrictions
# -o smtpd_sender_resterrictions = $ MUA_SENDER_RESTRICTIONS
# -o smtpd_recipient_resterrictions =
# -o smtpd_relay_resterrictions = pull_sasl_authenticated,拒绝
# -o milter_macro_daemon_name =始发
# 628 inet n -y-- qMQPD
# QMGR UNIX N -N 300 1 OQMGR
# -o smtp_helo_timeout = 5 -o smtp_connect_timeout = 5
#
# =================================================================
# 与非PostFix软件的接口。确保检查手册
# 非postFix软件的页面以查找所需的选项。
#
# 以下许多服务都使用后四个管道(8)交付
# 代理人。 有关$ {收件人}的信息,请参见管道(8)人页面
# 和其他消息信封选项。
# =================================================================
#
# MailDrop。有关详细信息,请参见《 Postfix MailDrop_readme文件》。
# 也在main.cf中指定:maildrop_destination_recipient_limit = 1
#
#
# =================================================================
#
# 最近的Cyrus版本可以使用现有的" LMTP" Master.CF条目。
#
# 在cyrus.conf中指定:
# lmtp cmd =" lmtpd -a"听=" localhost:lmtp" proto = tcp4
#
# 在main.cf中指定以下一个或多个:
# Mailbox_transport = LMTP:INET:localhost
# virtual_transport = lmtp:inet:localhost
#
# =================================================================
#
# Cyrus 2.1.5(Amos Gouaux)
# 也在main.cf中指定:cyrus_destination_recipient_limit = 1
#
# Cyrus unix -n n--管道
# flags = drx user = cyrus argv =/cyrus/bin/deliver -e -r $ {sender} -m $ {extension} $ {user}
#
# =================================================================
# 通过Cyrus交付的旧例子。
#
# 旧卡鲁斯unix -n n--管道
# flags = r用户= cyrus argv =/cyrus/bin/deliver -e -m $ {extension} $ {user}
#
# =================================================================
#
# 有关配置详细信息,请参见Postfix Uucp_readme文件。
#
#
# 其他外部交付方法。
#
和OpendKim配置。 OpendKim使用域键标识电子邮件服务器,以使其更安全。没有它,邮件没有签名,也可能无法进入收件箱。
nano config/etc_default_opendkim
添加以下行:
# 注意:这是一个旧版配置文件。 Opendkim不使用它
# SystemD服务。请使用相应的配置参数
# /etc/opendkim.conf而不是。
#
# 以前,有人会在此处编辑默认设置,然后执行
# /lib/opendkim/opendkim.service.generate以生成Systemd替代文件
# /etc/systemd/system/opendkim.service.d/override.conf和
# /etc/tmpfiles.d/opendkim.conf。虽然这仍然是可能的,但现在是
# 建议直接在/etc/opendkim.conf中调整设置。
#
# daemon_opts =""
# 更改为/var/spool/postfix/run/opendkim以使用unix插座
# Chroot中的后缀:
# rundir =/var/spool/postfix/run/opendkim
#
# 注释以指定替代套接字
# 请注意,设置此设置将覆盖opendkim.conf中的任何插座值
# 默认:
# 在端口54321上的所有接口上聆听:
# 插座= INET:54321
# 在端口12345上收听回环:
# 套接字= inet:12345@localhost
# 在港口12345上的192.0.2.1听:
# 插座= INET:12345@192.0.2.1
nano config/etc_dovecot_conf.d_10-master.conf
添加以下行:
# default_process_limit = 100
# default_client_limit = 1000
# 默认VSZ(虚拟内存大小)服务过程的限制。这主要是
# 旨在捕捉和杀死在食物吃饭之前泄漏记忆的过程
# 一切。
# DEFAULT_VSZ_LIMIT = 256m
# 登录用户内部通过登录过程使用。这是最不信任的
# Dovecot系统中的用户。它根本不应该访问任何东西。
# default_login_user = dovenull
# 内部用户被无特权的过程使用。它应该与
# 登录用户,以免登录过程无法打扰其他过程。
# default_internal_user = dovecot
# 端口= 143
# 端口= 993
# SSL =是
# 在开始新过程之前,要处理的连接数量。通常
# 唯一有用的值是0(无限)或1。1更安全,但是0
# 更快。 <doc/wiki/loginprocess.txt>
# service_count = 1
# 始终等待更多连接的过程数量。
# process_min_avail = 0
# 如果设置service_count = 0,则可能需要增长此。
# vsz_limit = $ default_vsz_limit
# 端口= 110
# 端口= 995
# SSL =是
# 端口= 587
# 仅当您无法使用上述UNIX插座时创建INET侦听器
# inet_listener lmtp {
# 避免使LMTP在整个互联网上可见
# 地址=
# 端口=
# }
# 大多数内存都用于mmap()ING文件。您可能需要增加此
# 如果您有巨大的邮箱,请限制。
# vsz_limit = $ default_vsz_limit
# 最大限度。 IMAP过程的数量(连接)
# process_limit = 1024
# 最大限度。 POP3过程的数量(连接)
# process_limit = 1024
# 最大限度。 SMTP提交过程的数量(连接)
# process_limit = 1024
# auth_socket_path默认指向此userDB套接字。通常是
# Dovecot-LDA,Doveadm,可能是IMAP流程等。
# 该插座的完整权限能够获取所有用户名的列表
# 获取每个人的UserDB查找的结果。
#
# 默认的0666模式允许任何人连接到插座,但是
# 仅当UserDB返回一个" UID"字段时,UserDB查找才能成功
# 匹配呼叫者进程的UID。另外,如果呼叫者的UID或GID与
# 插座的UID或GID查找成功。其他任何事情都会导致失败。
#
# 要授予呼叫者的完整权限查找所有用户,请将模式设置为
# 除了0666以外的其他内容,Dovecot让内核执行
# 权限(例如,0777允许每个人完全权限)。
# 默认情况下,Auth Works过程作为root运行,以便可以访问
# /etc/shadow。如果不需要,则应将用户更改为
# $ default_internal_user。
# 用户= root
# 如果使用DICE代理,则邮件过程应可以访问其套接字。
# 例如:mode = 0660,group = vmail和global mail_access_groups = vmail
# 模式= 0600
# 用户=
# 组=
再次,请确保用您选择的域中替换所有这些文件中的域,femmebabe.com。编辑下一个文件,Dovecot的配置,
nano config/etc_dovecot_dovecot
并添加这些行
## Dovecot配置文件
# 如果您很着急,请参见http://wiki2.dovecot.org/quickconfiguration
# " doveconf -n"命令给出了更改设置的干净输出。使用它
# 将发布到Dovecot邮件列表时,而不是复制和粘贴文件。
# '# '角色和所有事物之后被视为评论。额外的空间
# 和标签被忽略。如果您想明确使用这些,请放置
# value inside quotes, eg.: key = "# char和尾随空格"
# 大多数(但不是全部)设置可以被不同的协议和/或
# 源/目标IPS通过将设置放置在各节内,例如:
# 协议IMAP {},本地127.0.0.1 {},远程10.0.0.0/8 {}
# 显示每个设置的默认值,不需要不需要
# 那些。这些是这样的例外:没有部分(例如命名空间{})
# 或默认情况下添加插件设置,它们仅列出为示例。
# 路径也只是基于配置的实际默认值的示例
# 选项。这里列出的路径是用于配置-Prefix =/usr
# -sysconfdir =/etc--localstedir =/var
# 启用安装的协议
# 逗号分开的IPS或主机列表在哪里聆听连接。
# "*"在所有IPv4接口中听," ::"在所有IPv6接口中聆听。
# 如果要指定非默认端口或更复杂的任何内容,
# 编辑conf.d/master.conf。
# 听= *,::
# 基本目录在哪里存储运行时数据。
# base_dir =/var/run/dovecot/
# 此实例的名称。在多实施设置中DoVeadm和其他命令
# 可以使用-i <senstance_name>选择使用哪个实例(替代方案
# 到-c <config_path>)。实例名称也添加到Dovecot进程中
# 在PS输出中。
# instance_name = dovecot
# 客户的问候消息。
# login_greeting = Dovecot准备就绪。
# 空间分离的受信任网络范围的列表。这些连接
# 允许IP覆盖其IP地址和端口(用于记录和
# 用于身份验证检查)。 disable_plaintext_auth也被忽略
# 这些网络。通常,您在此处指定IMAP代理服务器。
# login_trusted_networks =
# 空间分开的登录访问列表检查插座(例如TCPWRAP)
# login_access_sockets =
# 使用protxy_maybe =是,如果代理目标与这些IP匹配,
# 代理。这通常不是必需的,但是如果目的地
# IP是例如负载平衡器的IP。
# auth_proxy_self =
# 显示更多的详细过程标题(在PS中)。当前显示用户名,
# IP地址。可用于查看谁实际使用IMAP流程
# (例如,共享邮箱或使用相同的UID用于多个帐户)。
# verbose_proctitle = no
# 当Dovecot总体流程关闭时,所有过程是否应杀死。
# 将其设置为"否"意味着可以升级Dovecot的情况
# 强迫现有的客户连接关闭(尽管也可能是
# 如果升级是例如,一个问题由于安全修复)。
# shutdown_clients =是
# 如果非零,请通过与Doveadm Server的许多连接运行邮件命令,
# 而不是在同一过程中直接运行它们。
# doveadm_worker_count = 0
# UNIX插座或主机:用于连接到Doveadm服务器的端口
# doveadm_socket_path = doveadm-server
# 空间分离的环境变量列表保存在Dovecot上
# 启动并传递到其所有子过程。你也可以给
# 键=始终设置特定设置的值对。
# import_environment = tz
##
## 字典服务器设置
##
# 字典可用于存储密钥=值列表。这是几个
# 插件。字典可以直接访问或
# 字典服务器。以下dict block地图词典名称为uris
# 使用服务器时。然后可以使用格式使用URI来引用这些
# "代理:: <名称>"。
# quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext
# 大多数实际配置都包含在下面。文件名是
# 首先按其ASCII值分类,并按照该顺序进行分析。 00-exefixes
# 在文件名中,旨在使订购更容易理解。
# 还可以尝试包含配置文件,而无需给出错误
# 找不到:
# 允许Dovecot收听所有输入连接(IPv4 / ipv6)
为Dovecot用户添加密码:
nano config/etc_dovecot_passwd
在结肠之前,文件的第一部分是用户名。最后一部分" yourpassword"表示您要提供邮件服务器的密码。
team:{plain}yourpassword
接下来,opendkim配置
nano config/etc_opendkim.conf
并添加以下行:
# 这是用于签名和验证的基本配置。很容易
# 适合适合基本安装。请参阅opendkim.conf(5)和
# /USR/share/doc/opendkim/examples/opendkim.conf.sample完成
# 可用配置参数的文档。
# logwhy no
# 常见的签名和验证参数。在Debian中,"来自"标题是
# 过度签名,因为它通常是声誉系统使用的身份密钥
# 因此对安全性敏感。
# 签名域,选择器和键(必需)。例如,执行签名
# 对于域" example.com",selector" 2020"(2020._domainkey.example.com),
# 使用存储在/etc/dkimkeys/example.private中的私钥。更细粒度
# 可以在/usr/share/doc/opendkim/readme.opendkim中找到设置选项。
# domain example.com
# 选择器2020
# keyfile /etc/dkimkeys/example.private
# 在Debian中,OpendKim以用户" OpendKim"运行。当需要007的透明
# 使用与MTA的本地插座,该插座可以访问插座作为非特权
# 用户(例如,后缀)。您可能需要将用户的"邮政缀"添加到组
# 在这种情况下," Opendkim"。
# MTA连接的插座(必需)。如果MTA在Chroot监狱内,
# 必须确保可以访问插座。在Debian,Postfix运行
# /var/spool/postfix中的chroot,因此必须是一个unix插座
# 如下最后一行所示,配置如下所示。
# 插座本地:/run/opendkim/opendkim.sock
# 套接字INET:8891@localhost
# 插座INET:8891
# 主机要签名而不是验证,默认值为127.0.0.1。看到
# 有关更多信息,Opendkim(8)的操作部分。
# 内部主机192.168.0.0/16,10.0.0.0/8,172.16.0.0/12
# 信托锚启用DNSSEC。在Debian中,提供了信任锚文件
# 通过包装DNS-ROOT-DATA。
# 名称服务器127.0.0.1
# 从地址到用于签名消息的密钥中的地图域
# 一组应签署邮件的内部主机
nano config/etc_default_opendkim
并添加这些行
# 注意:这是一个旧版配置文件。 Opendkim不使用它
# SystemD服务。请使用相应的配置参数
# /etc/opendkim.conf而不是。
#
# 以前,有人会在此处编辑默认设置,然后执行
# /lib/opendkim/opendkim.service.generate以生成Systemd替代文件
# /etc/systemd/system/opendkim.service.d/override.conf和
# /etc/tmpfiles.d/opendkim.conf。虽然这仍然是可能的,但现在是
# 建议直接在/etc/opendkim.conf中调整设置。
#
# daemon_opts =""
# 更改为/var/spool/postfix/run/opendkim以使用unix插座
# Chroot中的后缀:
# rundir =/var/spool/postfix/run/opendkim
#
# 注释以指定替代套接字
# 请注意,设置此设置将覆盖opendkim.conf中的任何插座值
# 默认:
# 在端口54321上的所有接口上聆听:
# 插座= INET:54321
# 在端口12345上收听回环:
# 套接字= inet:12345@localhost
# 在港口12345上的192.0.2.1听:
# 插座= INET:12345@192.0.2.1
当我们准备设置我们的Postfix服务器时,我们将运行以下代码,并嵌入适当的域名。首先创建脚本
touch scripts/postfixsetup
sudo chmod a+x scripts/postfixsetup
nano scripts/postfixsetup
现在,在文本编辑器Nano中,编辑此文件,以包括您的域名而不是femmebabe.com。
# !/bin/bash
# 设置后缀
现在,运行完整的脚本以配置Postfix,Opendkim和Dovecot。
./scripts/postfixsetup
该脚本运行后,将其打印的最后一行复制并将其粘贴到您的DNS配置中,作为sendonly._domainkey的值。这是发送安全邮件时用于识别域的OpendKim密钥。
惊人的!在几天之内,您应该能够从服务器发送邮件,前提是所有内容的配置正确。
如果您只是为邮件服务器配置了DNS,则记录需要少于72小时。通常要快得多。您可以通过使用此命令检查服务器是否正在工作,提供了您的电子邮件:
echo "test" | mail -s "Test Email" youremail@gmail.com
如果所有内容似乎都正常工作,则应该能够使用服务器发送电子邮件。如果它不起作用,请尝试查看日志以查看可能的错误。
tail –lines 150 /var/log/mail.log
这将提供有关服务器发送的邮件以及它是否正常工作的详细信息。您也应该能够在收件箱中看到电子邮件,如果不存在,请检查垃圾邮件文件夹。
您还需要在设置中配置您的设置。py,以便您的电子邮件服务器可以与您的Django应用程序(项目)通信。在您的设置中添加或替换这些行
EMAIL_HOST_USER = 'team' # 'love@mamasheen.com'
请注意,我们正在使用配置文件获取密码。让我们像在文件的开始一样将此文件加载到设置中。
# 打开并加载配置
让我们创建此文件并在其上添加秘密键以及邮件密码。要生成一个秘密键,请使用此命令,最终都有您喜欢的长度:
openssl rand -base64 64
现在,复制openssl生成的文本并编辑/etc/config.json
sudo nano /etc/config.json
将以下行添加到您的文件中,并使用OpenSSL生成的秘密密钥的键。
{
"SECRET_KEY": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX-generated-using-openssl)",
"EMAIL_HOST_PASSWORD": "yourpassword"
}
JSON格式简单易于使用,我们也可以以这种方式声明我们要在项目中使用的其他密钥,并将其与我们的项目目录分开,以便其他用户不能写信给它们,因此无法单独从我们的项目目录中阅读它们。这是适用于API键的练习,我们将在这里使用多个键。
您还需要备份您的项目,以确保所有已保存的东西都可以保存,即使您不再希望租用服务器,也可以在以后恢复工作。
sudo backup
现在,尝试从Web服务器发送HTML电子邮件,提供从命令行发送的电子邮件。在外壳中查询您的用户实例,然后通过Django向该用户发送HTML电子邮件。在代码中将我的名字更改为您的用户名。
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
只要一切都正确设置,您现在将在Web应用程序发送的邮箱中收到一封欢迎电子邮件。好工作!你走了很长一段路。
我想补充一点,如果您在这样的项目工作时根本遇到任何错误,请随时寻找答案并寻求帮助。 Google除其他搜索引擎外,是寻找编程帮助的好资源。只需搜索您遇到的错误,您就可以看到其他人如何解决问题。另外,欢迎您与我,您的教育工作者(老师,教授,教师),互联网上的任何同行者联系,他们可以提供编程帮助,或再次咨询本书或其他资源,以找到解决您所遇到的问题的解决方案。我了解这并不容易,但是即使您已经阅读了这么多的文章并且没有编写任何代码,您也在从头开始构建Web应用程序很多。拍拍自己的后背,你做得很好。
感谢您抽出宝贵的时间阅读本第三版网络开发指南。在将来的版本中,我将包括文档开头讨论的更多重要示例,我们将深入研究软件和硬件开发的世界。请继续关注即将发生的事情,我期待教您如何构建令人难以置信的软件。在下一版中见!
https://glamgirlx.com/zh-cn/practical-web-based-deep-learning-and
https://glamgirlx.com/zh-cn/practical-web-based-deep-learning-and -
使用此地址给我留言比特币中的小费: 3KhDWoSve2N627RiW8grj6XrsoPT7d6qyE