1个不稳定版本

0.8.0 2022年5月9日

#5 in #niftygate


用于 niftygate

MIT 许可证

11KB
278

niftygate - 通过NFT所有权实现即插即用访问控制

简介

使用任何部署在任何区块链上的智能合约,无需修改代码即可访问互联网上的任何内容。

概述

如果您将代币比作进入俱乐部的入场券,NiftyGate就是门口的保安。

  • 兼容典型的代币标准,包括可互换和不可互换的代币(ERC20、ERC721、ERC777和ERC1155)。

  • 与任何通过WebSocket与Web3通信的区块链都兼容。

  • 位于任何使用HTTP通信的服务之前。

  • 具有用于与客户端应用程序一起使用的嵌入式模式。

  • 与任何支持HTTP头部的身份验证系统集成。

  • 附带选择、部署、调试和审计兼容智能合约的工具。

  • 作为一个单一的、自包含的二进制文件提供。

  • 跨平台(在Linux和macOS上进行了测试,应在其他地方也能工作)。

  • 开源(MIT许可),用Rust编写。

这是什么?

niftygate是一个HTTP服务的代理,它验证签名,为这些服务提供认证层。它还具有为客户端自动将签名注入请求的功能。

我能用它来做什么?

截至0.2,支持智能合约。这些允许使用代币作为受保护服务的可转让许可证。

一些示例

  • 一个允许授权用户下载资产的OCI仓库。
  • 一个允许项目支持者获得优先支持的问题跟踪器。
  • 一个允许客户按比例投票权对功能开发进行投票的项目路线图。
  • 一个需要N-of-M授权用户才能发布到生产的部署管道。
  • 一个具有去中心化许可证的应用商店,其中作者保留许可证控制权,而不是平台。
  • 一个数字图书馆,借阅由代币管理,归还由智能合约强制执行。

为什么会有这个东西?

这实际上是两个问题,让我们来分解一下...

为什么这个概念有用?

基于签名的身份验证避免了基于密码的身份验证的许多陷阱。服务器只需要知道公钥,如果这些公钥泄露了...谁会在意呢?它们是公开的密钥。

假设两种情况下都有合理的用户界面,用户可以像更改密码一样轻松地旋转密钥。他们可以将一组权限委派给其他密钥(就像我们在其他地方使用访问令牌所做的那样)。

密钥是用户生成的,而不是用户记忆的。这完全消除了密码重复等问题。

为什么这种方法实用呢?

以代理的形式实现这可以使其在不修改的情况下应用于大多数现有的HTTP(S)应用。

将签名与验证分离,可以更细粒度地控制对私钥的访问。这也意味着代理只能在需要的地方使用。如果客户端应用可以本地处理签名,那么它应该这样做。

将其实现为一组可组合的中间件,使其易于扩展,并且可以(负责任地)尝试新功能。

如果您喜欢这种类型的工具,它还可以部署为边车容器。

我如何获得这个卓越的工具呢?

cargo install niftygate

或者,如果您喜欢Docker

docker pull colstrom/niftygate:0.8.0

我如何使用它?

首先,您需要某种服务,您想在前面放置代理。

为了演示和开发目的,niftygate包括一个嵌入的示例服务,该服务在响应体中打印请求头。

$ niftygate demo
tide::log Logger started
    level DEBUG
tide::server Server listening on http://127.0.0.1:8080

接下来,您需要有一个Ethereum JSON-RPC (Web3)服务,以便niftygate可以与之交互。Ganache是本地使用的优秀选项,所以本文档的其余部分假设使用Ganache。

首先,选择您想要用于签名的地址:显示如何在Ganache中选择地址的截图

然后,找到该地址的私钥:显示如何在Ganache中找到私钥的截图

将此私钥添加到环境变量中

使用fish

set -x SECRET_KEY_DATA PUT_THE_DATA_HERE

使用老式shell,如bash

export SECRET_KEY_DATA=PUT_THE_DATA_HERE

现在您可以运行它了!让我们看看帮助信息

$ niftygate web3 --help

niftygate-web3 0.1.0
Runs the proxy service

USAGE:
    niftygate web3 [FLAGS] [OPTIONS]

FLAGS:
    -h, --help                             Prints help information
    -V, --provides-account-verification    verify signatures and provide account addresses
    -B, --provides-balances                provide account balances
    -S, --provides-signatures              provide signatures
        --version                          Prints version information

OPTIONS:
        --address-header <name>        [env: ADDRESS_HEADER=]    [default: X-Web3-Account-Address]
    -b, --backend <url>                [env: BACKEND=]           [default: http://127.0.0.1:8080]
        --balance-header <name>        [env: BALANCE_HEADER=]    [default: X-Web3-Account-Balance]
        --balance-maximum <amount>     [env: BALANCE_MAXIMUM=]
        --balance-minimum <amount>     [env: BALANCE_MINIMUM=]
    -u, --balance-scale <unit>         [env: BALANCE_SCALE=]     [default: Wei]
    -c, --challenge <phrase>           [env: CHALLENGE=]         [default: totes-legit]
    -l, --listen <address>             [env: LISTEN=]            [default: 0.0.0.0:8000]
    -K, --secret-key-data <hex>        [env: SECRET_KEY_DATA=]
    -k, --secret-key-file <path>       [env: SECRET_KEY_FILE=]
        --signature-header <name>      [env: SIGNATURE_HEADER=]  [default: X-Web3-Signature]
    -w, --web3-rpc-url <url>           [env: WEB3_RPC_URL=]      [default: ws://127.0.0.1:7545]

所有这些选项都是可选的,尽管除非您启用其中至少一个,否则它不会做任何事情。让我们关注两种场景。

场景1 - 提供签名

在这种模式下,niftygate会为它处理的每个请求添加一个签名。

$ niftygate web3 --provides-signatures
tide::log Logger started
    level DEBUG
tracing::span new
tracing::span build
isahc::agent agent waker listening on 127.0.0.1:61558
isahc::agent agent_thread; port=61558
isahc::agent agent took 409.705µs to start up
tide::server Server listening on http://0.0.0.0:8000

需要秘密(私钥)来签名这些请求。它可以作为文件(--secret-key-file)或十六进制字符串(--secret-key-data)提供。如果都提供了,则忽略--secret-key-file。这些也可以通过环境变量提供,这正是我们上面所做的。

此密钥用于对挑战短语(目前由--challenge提供)进行签名,挑战短语应为客户和服务器所知。它不需要是私有的。

此签名将使用--signature-header提供的头添加到请求中。

场景2 - 提供账户验证

在这种模式下,niftygate期望请求包含签名头,并将拒绝不包含签名头的请求。这些头将被验证,并且用于签名的地址将被添加到它处理的每个请求中。

请注意,客户端不会明确提供地址。他们签署一个双方都知的挑战短语,并且签名地址可以从有效的签名中恢复。

$ niftygate web3 --provides-account-verification
tide::log Logger started
    level DEBUG
tracing::span new
tracing::span build
isahc::agent agent waker listening on 127.0.0.1:56181
isahc::agent agent_thread; port=56181
isahc::agent agent took 312.747µs to start up
tide::server Server listening on http://0.0.0.0:8000

如果签名有效,则使用由--address-header指定的头将地址添加到请求中。假设后端知道如何处理此头。例如,您可以使用X-Remote-User头将niftygateDex集成。

场景3 - 提供账户余额

在此模式下,niftygate期望请求包含账户头,并将拒绝不包含该头的请求。该头中给出的地址的余额将被添加到它处理的每个请求中。

$ niftygate web3 --provides-balances
tide::log Logger started
    level DEBUG
tracing::span new
tracing::span build
isahc::agent agent waker listening on 127.0.0.1:54608
isahc::agent agent_thread; port=54608
isahc::agent agent took 313.524µs to start up
tide::server Server listening on http://0.0.0.0:8000

默认情况下,这并不关心余额是多少,它只是将余额添加到由--balance-header指定的头中。然而,有一些选项可以基于余额限制访问。

可以使用--balance-minimum选项来要求最小余额。这可以作为“投入筹码”的一种形式,通过要求非零余额(这可以用于防止机器人或帮助限速),或者如果你有其他原因,可以仅允许大玩家访问。

可以使用--balance-maximum选项来拒绝余额超过指定金额的账户。这可以用于限制风险,或者如果你愿意,仅允许普通人访问。

可以使用--balance-unit选项来方便地缩放上述限制。一个Gwei有多少个零?无需记住,只需设置--balance-unit=Gweiniftygate将内部进行缩放。但余额头仍然以Wei为单位。

备注

上面的示例独立使用功能,但它们都被实现为可组合的中间件。您可以在单个进程中启用所有这些。同时使用签名和验证在同一个进程中似乎有些荒谬,但没有理由您不能这样做。

试试吧!

假设您已启用所有功能,并且代理位于演示应用程序之前,如果您使用curl查询每个应用程序,您将看到如下内容

直接查询演示应用程序

$ curl -s http://127.0.0.1:8080 | sort
accept: ["*/*"]
host: ["127.0.0.1:8080"]
user-agent: ["curl/7.64.1"]

通过代理查询

$ curl -s http://127.0.0.1:8000 | sort
accept-encoding: ["deflate, gzip"]
accept: ["*/*"]
content-length: ["0"]
content-type: ["application/octet-stream"]
forwarded: ["by=127.0.0.1:8000;for=\"127.0.0.1:52698\";host=127.0.0.1:8000;proto=http"]
host: ["127.0.0.1:8000"]
user-agent: ["curl/7.64.1"]
x-web3-address: ["24f9f97c9e540fed57ef81f6c9aeabdb6fc73acd"]
x-web3-balance: ["100000000000000000000"]
x-web3-signature: ["krpQZO9WpgAEso2uk6eAKDy29QjeVtr+gdDZ7iG4bFkYiTfNvTvU5l4bb2iod5F4Ab8a8tJqzXHSXLkyz9U/gRs="]

智能合约

嵌入式预设

为了帮助您开始,niftygate内置了OpenZeppelin项目的一些预设。它们解决了某些更常见的用例,并且(根据OpenZeppelin文档)是生产就绪的。

目前,包括五个预设以及部署和交互每个预设的实用工具。这些可以在contract子命令下找到。

为了帮助您确定合适的合约,请检查guide子命令。在那里,您将找到一个交互式程序,它会问您几个简单的问题,并提供推荐。

路线图

愿望清单(不分先后)

Infura集成

支持RFC-7486(HTTP源绑定认证)

  • 将固定消息替换为随机挑战,添加nonce和过期时间等。

可选端点,用于在浏览器中提供内嵌脚本支持。

X509 支持

  • 这提供了一个替代方案,当更倾向于信任链模型时。

PGP 支持

  • 这提供了一个替代方案,当更倾向于信任网模型时。

许可证

niftygate遵循MIT许可证。详见LICENSE.txt的完整文本。

niftygate内嵌了合同ABI规范和来自OpenZeppelin Contracts的文档摘录。这些也按照MIT许可证的条款分发此处

NiftyGate能帮我什么?

我已经有一个网站和一个智能合约

以服务器模式运行niftygate,提供您网站的地址和合约的地址。

我有一个网站,但我不想使用智能合约

以服务器模式运行niftygate,将niftygate指向您网站的地址,它将让用户使用钱包登录。

我有一个非Web应用程序,并想与智能合约接口

将niftygate编译为库,并嵌入到您的应用程序中。

我有一个非Web应用程序,但不想修改我的代码。

以客户端模式运行niftygate,并将您的应用程序指向它。

我使用容器平台,如Docker或Kubernetes。

以客户端或服务器模式运行niftygate,作为旁路容器部署。

我使用Kubernetes,并想将智能合约集成到控制器中。

使用contract events --stream模式。这将在STDOUT上输出匹配的事件作为紧凑的JSON。

我没有智能合约,但我想有一个。

部署niftygate附带的一个内置合约,无需编写代码!

我不知道我需要什么类型的智能合约。

使用niftygate内建交互式指南。

我没有连接的以太坊节点。

在infura.io注册一个账户,并将niftygate指向它。免费账户每天允许100k个请求,如果您需要更多,他们有付费计划。

我想使用私有区块链。

试试看。niftygate的大部分开发都是在私有区块链上完成的。只要它支持通过WebSockets的JSON-RPC + Web3,就应该没问题。

Ganache和geth是不错的选择,具体取决于您的需求。

我想使用自己的身份平台。

以服务器模式运行niftygate,并告诉它应该传递哪些头部。

依赖关系

~3–11MB
~101K SLoC