教程:在IPFS上构建零依赖注释应用程序-第一部分

2019-10-18 16:57:55

这是一个分为两部分的教程的一部分。第一部分着重于身份验证,第二部分着重于从IPFS发布和获取内容。

      注意:本教程最初包含基本加密,但是由于某些人可能在复制和粘贴时未考虑使用生产中记录的加密的安全性问题,因此我已完全删除了基本加密。

      这是一个分为两部分的教程的一部分。第一部分着重于身份验证,第二部分着重于从IPFS发布和获取内容。

      新兴的Web 3.0技术有望带来用户控制的回报-不仅是数据的控制,还是互联网的控制。曾经有一段时间我们使用的网络不受寡头垄断的支配。这是在我们脱离AOL的围墙花园模型之后。我们变得自由,联系,参与。但是随后,事情又开始关闭了。亚马逊上升了。Google成为权力真空。Facebook决定它将是AOL 2.0。现在,借助去中心化的Web技术,我们有机会收回以前拥有的Web。IPFS只是Web 3.0空间中的一种解决方案,但是它使我们瞥见了可能的解决方案。今天,我们将构建一个简单的notes应用程序,但首先,让我们了解什么是IPFS。

      IPFS —行星际文件系统—希望取代http协议,成为全世界获取内容的方式。http和IPFS之间的最大区别是https是基于位置的,而IPFS是基于内容的。但这实际上是什么意思?这意味着在当今的网络中,您必须从单一来源获取您的内容(越来越多的公司开始使用AWS S3存储桶)。IPFS基于内容,意味着您基于文件的内容来获取文件。您告诉IPFS对等网络,您正在寻找具有确切内容的文件,网络中第一个拥有该内容的对等体将返回该文件。许多同龄人可能拥有此内容,该内容比当今的网络具有更高的审查抵抗力,但与当今的网络相比,它还提供更多的容错能力。如果我之前提到的S3存储桶由于某种原因而无法访问,则无法获取内容。但是,如果无法在IPFS上保存拥有您要查找的内容的同位体,则网络将继续搜索,直到拥有该内容的同位体可以访问。

      我们可以花什么IPFS做一整篇文章,以及它如何可以帮助网页,但已经有大量的文章关于这一点。既然您已经对IPFS有了基本的了解,那么在开始学习本教程之前,我们还需要了解另外一件事:

内容固定。

      将内容添加到IPFS网络时,并不意味着它是永久性的。就像90年代的旧音乐传输服务一样,只要有对此内容的需求,IPFS网络将继续托管该内容。但是,当需求下降时,可以并且很可能将这些内容收集为垃圾。但是,如果您是唯一要访问该文件的人,即使您每年仅访问一次该文件,该文件仍可访问,该怎么办呢?

      这就是内容固定的作用。您可以运行IPFS节点并自己固定内容,但是有一些缺点。A)对于新手来说不容易,并且B)如果您在本地计算机上运行该节点,除非该计算机始终连接到Internet,否则您将无权访问内容。

      这就是为什么内容固定服务随着IPFS的兴起而增长的原因。皮纳塔就是其中一种。Pinata运行多个IPFS节点,并为开发人员提供了一个简单的API,可以插入该API以在IPFS上存储和获取内容。他们还将固定内容以确保其可用性。

      今天,我们将结合使用我自己的产品SimpleID和Pinata在IPFS上构建零依赖的Notes应用程序。让我们开始吧。

设定

      我们将使用SimpleID API在普通JavaScript中构建此应用,以使尽可能多的JavaScript框架的开发者都可以使用它。因此,您将需要以下内容:

      · 文字编辑器

      而已。

      通过创建您的项目来进行设置。在终端上,无论您希望在计算机的文件夹层次结构中的哪个位置创建目录。对我来说,这是在我的/documents/development文件夹中。

      首先,创建一个目录来保存该应用程序:mkdir ipfs-notes。您可以根据需要给应用程序打电话。

      然后,切换到该目录:cd ipfs-notes。完成后,我们就可以开始了。由于我们正在使用可从浏览器调用的API端点,因此无需安装其他任何东西。

      现在,您需要获取一个SimpleID API密钥。您可以在此处注册SimpleID免费计划。注册后,系统会要求您验证您的电子邮件地址。这样做,然后就可以创建一个项目并选择要包含在项目中的模块。单击“创建项目”按钮,为其命名,并提供一个项目URL(注意:出于安全原因,该URL必须是唯一的,因此,如果您没有该URL,则可以对其进行组合或提供计划的URL。部署到最终)。单击编辑模块按钮,然后为您的身份验证模块选择Blockstack。切换到存储模块,然后选择Pinata。点击右下角的“保存”,然后通过单击左上角的菜单并选择“帐户”返回“帐户”页面。

      您需要做的最后一件事是获取开发人员ID和API密钥。单击查看项目,您将在其中看到两个项目。将它们保存在某个地方,因为我们即将开始编写代码!

开始项目

      在项目文件夹的Terminal中,我们只创建一个文件:

image.png

      在项目目录的根目录中,创建一个名为的文件main.js。在整个项目中,您只有两个文件:

      · index.html

      · main.js

      让我们确保一切正常。在您的main.js文件中,添加以下内容:

image.png

image.png

      好的,这是怎么回事?好吧,我们声明了一个全局变量,它是一个包含我们配置选项的对象。在该配置对象中,我们包括开发人员ID和API密钥。但是我们还需要告诉SimpleID我们正在使用哪些身份验证模块和存储模块(请记住:我们使用Blockstack进行身份验证,使用Pinata进行存储)。appOrigin应该与您在创建项目和生成API密钥时输入的内容匹配。范围数组仅授予您访问某些功能的权限。

      您会注意到async我们两个功能前面的关键字。我们将发出产生诺言的http请求,并且需要在执行其他代码之前等待诺言解析,因此我们需要使这些函数为async / await函数。您很快就会明白我的意思。

      现在,我们需要创建一个注册表单并将该表单的结果传递给signUp函数。对我来说,我认为如果用户未登录,则应该首先显示“注册表单”页面,因此,我将创建一个变量来指定该页面。在脚本标记之间的JavaScript代码顶部,我要添加以下代码:

image.png

      非常基本的形式。稍后我们将对其进行样式设置,但您会在开头的div中注意到样式属性。为什么我们不显示此表格?好吧,我们需要根据一些变量有条件地显示它:

      · 用户已经登录了吗?不要显示它。

      · 用户是否已决定登录但不注册?不要显示它。

      · 页面正在加载吗?不要显示它。

      我们如何利用我们先前创建的变量来有条件地呈现此表单?好吧,在我们这样做之前,我们还要创建我们的登录表单。我们可以只复制注册表单并进行一些调整。您应该以如下形式结束:

image.png

      用户登录时,我们不需要电子邮件字段。我们还需要更改特定于登录而不是登录的元素ID。我们还更新了在表单提交和按钮标签上调用的功能。很简单

      现在,我们可以使我们创建的那些变量为我们做一些工作。我们希望这个新功能可以在每次加载页面和执行某些操作时调用更新。因此,让我们这样做。在声明所有变量之后,在JavaScript代码的顶部,让我们调用一个名为的函数,pageLoad()并在其下面创建实际的函数:

image.png

tXwjYWNvxOM9TCAf17t7bLP1U28GNmNGT34e2j1i.png

      有很多不同的方法可以解决此问题,但这是一个非常简单的解决方案,因此我将继续进行下去。如果愿意,欢迎您实施其他策略。

      我们应该在html的主体中添加几个有条件的渲染部分。我们需要一个用于加载屏幕,一个用于容纳已登录用户的应用程序屏幕。我们可以像这样简单地模拟它:

image.png

      现在,我们已经准备好实际注册并登录!让我们开始吧。您先前已经创建了配置对象。因此,现在我们要做的就是捕获用户的注册凭据。

      有几种方法可以做到这一点,但是为了使其尽可能简单,我们将仅获取输入值。在signUp函数内部,添加以下内容:

image.png

      这仅仅是我们最终向SimpleID API发出发布请求所需要的开始。我们已经将loading变量翻转为true,并且正在捕获注册表单的输入字段。您会注意到,pageLoad()在输入元素被捕获为变量之后,我们将调用函数。这只是一项安全措施,因为我们正在更新页面状态以显示加载屏幕而不是表单,并且我们要确保已存储用户名,密码和电子邮件并可以使用。

      我要花一点时间指出我没有对这些输入元素进行任何验证。这超出了本教程的范围,但是您绝对应该这样做。

      我们还存储了两个SimpleID API端点作为变量。实际上,我们都需要这两者来创建帐户。第一个创建用户的钥匙串(用户信息,私钥等)。第二个返回必要的特定于应用程序的信息,以用于建立用户会话。

      现在,在继续signUp()功能代码之前,我们应该设置我们的HTTP请求代码。每当我们需要向SimpleID API发出请求时,我们都将调用此函数,结果将是一个承诺。因此,继续创建一个新函数postToApi():

image.png

      根据SimpleID API文档,我们知道我们正在发送表单数据,因此已设置了内容类型。您可能在signUp之前的函数中已经注意到,我们捕获了一个名为的变量,data并且该变量具有urlencoded格式,我们需要将此表单数据传递给API。

      确保apiKey用在SimpleID中创建项目时收到的API密钥替换。

      因为我们已经做出了承诺,所以当承诺解决时,响应将被发回。现在,我们可以在我们signUp之前编写的代码下面的函数中执行此操作:

Aej9n0clS9axF9uNo67yhOjIX1K1DyVoZHjG9YOd.pngimage.png

      好的,看来这里发生了很多事情,但是还不错。我们说的是,如果第一个API调用没有错误,那么让我们开始第二个API调用。根据SimpleID文档,我们需要提供devID用户的username,用户的password,应用的url以及配置文件对象。让我们快速地谈论那个配置文件对象。

      SimpleID支持多种Web 3.0协议,其中一种协议是Blockstack。Blockstack具有此配置文件概念,允许用户彼此交互并共享数据。我们希望确保始终有一个配置文件对象准备就绪,以防您作为开发人员决定构建使用Blockstack存储的应用程序,或者如果用户决定使用也实现了SimpleID的另一个应用程序。可见,用户可以在多个应用程序中使用相同的帐户凭据。因此,只需了解配置文件格式(如SimpleID Docs中所述)就可以采用上述格式。而且,当然,我们必须对其进行URIEncode编码以支持将表单数据发布到API。

      url您提供给配置文件对象的变量和url必须是格式正确的url,因此,如果您在没有网络服务器的情况下进行开发,则不能仅使用window.location.origin。如果是这种情况,则应提供一个类似的来源http://localhost:3000或计划将应用程序部署到的最终URL。

      您可能还会在我们发送给API的数据中记下的标志development。在生产中,请确保这始终是正确的。

      在我们的else语句中,如果第一个API调用失败,我们希望将应用程序状态翻转回登录屏幕,并在控制台日志中记录某种消息。但是,如果一切成功,并且我们调用了第二个API端点,则需要嵌套一些其他逻辑以支持该端点上的成功和失败。在下面添加以下内容console.log(userData):

image.png

      好的,所以这里我们要说的是第二次API调用是否成功,让我们解析响应(这是API返回的字符串)。然后,我们想将用户的用户名添加到我们现在创建的对象中(因为API不返回用户名)。完成此操作后,我们需要一种方法来保留用户的登录会话。有不同的处理方法,关于在本地存储中应存储哪种类型的数据存在争议。对这些主题进行自我教育,但是为了了解本教程,我将把会话信息放入本地存储中。

      我们还需要翻转状态变量,并通过调用来更新应用程序状态pageLoad()。当然,如果第二个API调用失败,则该用户将无法登录,我们需要将其返回到注册屏幕。

      如果您保存此设置,则实际上可以继续注册一个帐户。这里要注意的一件事是,如果只是index.html在浏览器中打开文件而不是运行本地Web服务器,则将需要像这样的CORS扩展。原因是API端点期望基于浏览器的请求具有格式正确的来源。以开头的原点File://是不可接受的。但是,如果您使用CORS扩展程序,那么一切都会准备就绪。

      如果注册时一切顺利,您将看到注册表单消失,弹出一个加载指示器,然后This is the app将显示我们之前用作占位符的文本。

      这太棒了,但是我们还需要做两件事。第一,如果用户刷新页面会怎样?好吧,尝试一下。看起来用户正在自动注销?另外,用户如何登录?我们尚未连接登录功能。

      让我们快速处理会话持久性。在main.js该pageLoad()函数下的文件中,我们只需要对本地存储进行快速检查,以获取用户的会话信息。如果您从上面遵循我的代码,则可以将其添加到pageLoad()函数顶部:

4vT5ACeB0oqNYQ5SCdrUkNcksxRYZSw7mnuJCPRx.png

image.png

      除了跳过第一个API调用之外,此代码的作用与注册代码相同。因此,如果您仍在注册页面上,请单击屏幕顶部的登录按钮,输入以前用于注册的凭据,然后应该会看到页面更新为正在加载,然后更新为This is the app文本。

      现在,由于我们保留了用户会话,因此您应该能够刷新页面,并且用户仍将登录。如果该操作正常,那么我们只需要做最后一件事。我们需要让用户退出。

      返回您的html文件,找到我们编写的应用代码This is the app。让我们在该文本上方添加一个按钮,上面写出“退出”。

image.png

IPFS

image.png

最新推荐