datasette-auth-tokens 由 simonw 提供

星标

README 源代码

datasette-auth-tokens

PyPI Changelog Tests License

用于使用 API 令牌进行访问认证的 Datasette 插件

安装

在与 Datasette 相同的环境中安装此插件。

datasette install datasette-auth-tokens

硬编码令牌

阅读关于 Datasette 的认证和权限系统

此插件允许您配置秘密 API 令牌,这些令牌可用于向 Datasette 发出认证请求。

首先,创建一个随机 API 令牌。一个有用的方法如下

python -c 'import secrets; print(secrets.token_hex(32))'
5f9a486dd807de632200b17508c75002bb66ca6fde1993db1de6cbd446362589

确定此令牌应代表哪个 actor(参与者),例如

{
    "bot_id": "my-bot"
}

然后您可以使用 "allow" 块为该令牌提供访问特定操作的权限。要启用对已配置的可写 SQL 查询的访问,您可以在 config.json(适用于 Datasette 1.0)或 metadata.json 中使用以下配置

{
    "plugins": {
        "datasette-auth-tokens": {
            "tokens": [
                {
                    "token": {
                        "$env": "BOT_TOKEN"
                    },
                    "actor": {
                        "bot_id": "my-bot"
                    }
                }
            ]
        }
    },
    "databases": {
        ":memory:": {
            "queries": {
                "show_version": {
                    "sql": "select sqlite_version()",
                    "allow": {
                        "bot_id": "my-bot"
                    }
                }
            }
        }
    }
}

这使用了 Datasette 的秘密配置值机制,允许将秘密令牌作为环境变量传递。

像这样运行 Datasette

BOT_TOKEN="this-is-the-secret-token" \
    datasette -c config.json

您现在可以像这样运行经过认证的 API 查询

curl -H 'Authorization: Bearer this-is-the-secret-token' \
  'http://127.0.0.1:8001/:memory:/show_version.json?_shape=array'
[{"sqlite_version()": "3.31.1"}]

此外,您还可以允许将令牌作为查询字符串参数传递,尽管考虑到 URL 中包含秘密令牌的安全隐患,此功能默认禁用。这可能有助于方便地在不同服务之间嵌入数据。

使用 param 配置值启用此功能

{
    "plugins": {
        "datasette-auth-tokens": {
            "tokens": [
                {
                    "token": {
                        "$env": "BOT_TOKEN"
                    },
                    "actor": {
                        "bot_id": "my-bot"
                    },
                }
            ],
            "param": "_auth_token"
        }
    },
    "databases": {
        ":memory:": {
            "queries": {
                "show_version": {
                    "sql": "select sqlite_version()",
                    "allow": {
                        "bot_id": "my-bot"
                    }
                }
            }
        }
    }
}

您现在可以像这样运行经过认证的 API 查询

curl http://127.0.0.1:8001/:memory:/show_version.json?_shape=array&_auth_token=this-is-the-secret-token
[{"sqlite_version()": "3.31.1"}]

托管令牌模式

datasette-auth-tokens 提供托管令牌模式,其中令牌存储在 SQLite 数据库表中,并且插件提供创建和撤销令牌的界面。

要启用此模式,请在您的插件配置中添加 "manage_tokens": true

{
    "plugins": {
        "datasette-auth-tokens": {
            "manage_tokens": true
        }
    }
}

这将在 Datasette 菜单中添加一个“创建 API 令牌”选项。

创建的令牌将保存在一个新的 _datasette_auth_tokens 表中。

用户需要 auth-tokens-create 权限来创建令牌。授予此权限的一种方法是在您的配置中添加以下 "permissions"

{
    "permissions": {
        "auth-tokens-create": {
            "id": "*"
        }
    }
}

使用 Datasette 菜单中的“创建 API 令牌”选项或导航到 /-/api/tokens 来创建和管理令牌。

创建新令牌时,将向您显示一个签名的令牌字符串。您需要妥善保存它,因为它不会直接存储在数据库表中,并且只能检索一次。

如果您连接了多个数据库到 Datasette,您需要指定哪个数据库用于存储 _datasette_auth_tokens 表。您可以使用 manage_tokens_database 设置来完成此操作

{
    "plugins": {
        "datasette-auth-tokens": {
            "manage_tokens": true,
            "manage_tokens_database": "tokens"
        }
    }
}

现在像这样启动 Datasette

datasette -c config.json mydb.db tokens.db --create

如果 tokens.db 数据库文件不存在,可以使用 --create 选项告知 Datasette 创建它。

在 Datasette 1.0 中,您可以改用 -s 选项,如下所示

datasette \
  -s plugins.datasette-auth-tokens.manage_tokens true \
  -s plugins.datasette-auth-tokens.manage_tokens_database tokens \
  -s permissions.auth-tokens-create.id '*' # to enable token creation

查看令牌

默认情况下,用户只能在 /-/api/tokens 页面上查看他们自己创建的令牌。

授予 auth-tokens-view-all 权限,以允许用户查看所有令牌,即使是其他用户创建的令牌。

撤销令牌

创建令牌的用户可以通过点击从 /-/api/tokens 链接到的令牌页面底部的“撤销此令牌”按钮来撤销该令牌。

拥有 auth-tokens-revoke-all 权限的用户可以撤销任何令牌。

来自您数据库的自定义令牌

如果您决定不使用托管令牌模式,您可以转而配置 datasette-auth-tokens 使用存储在您自己的自定义数据库表中的令牌。

您可以通过配置一个自定义 SQL 查询来完成此操作,该查询将执行以测试传入令牌是否有效。

您的查询需要接受一个 :token_id 参数,并至少返回两列:一列命名为 token_secret,另一列命名为 actor_* - 通常是 actor_id。可以返回更多以 actor_ 为前缀的列,以提供经过认证的 actor 的更多详细信息。

以下是一个简单的配置查询示例

select actor_id, actor_name, token_secret from tokens where token_id = :token_id

这可以针对像这样的表运行

token_id token_secret actor_id actor_name
1 bd3c94f51fcd 78 Cleopaws
2 86681b4d6f66 32 Pancakes

令牌的格式是:令牌 ID,然后是连字符,然后是令牌 secret。例如

  • 1-bd3c94f51fcd
  • 2-86681b4d6f66

SQL 查询将使用连字符之前的部分作为 :token_id 参数执行。

将查询返回的 token_secret 值与令牌中连字符之后的部分进行比较,以检查令牌是否有效。

带有 actor_ 前缀的列将用于填充 actor 字典。在上面的示例中,令牌 2-86681b4d6f66 将成为一个 actor 字典 {"id": 32, "name": "Pancakes"}

要配置此功能,请在您的插件配置中使用一个 "query" 块,如下所示

{
    "plugins": {
        "datasette-auth-tokens": {
            "query": {
                "sql": "select actor_id, actor_name, token_secret from tokens where token_id = :token_id",
                "database": "tokens"
            }
        }
    },
    "databases": {
        "tokens": {
            "allow": false
        }
    }
}

这里的 "sql" 键包含 SQL 查询。"database" 键是应执行查询所针对的附加数据库文件的名称 - 在此示例中,它将针对 tokens.db 执行。

保护您的自定义令牌

如果您实现了上面从您自己的 tokens 表读取 token_secret 的自定义模式,您需要注意,任何对您的 Datasette 实例具有读取访问权限的人都可以从您的表中读取这些令牌。这可能不是您想要的结果!

为了避免这种情况,您应该锁定对该表的访问。上面的配置示例展示了如何使用 "allow": false 块来拒绝所有对该 tokens 数据库的访问。

请查阅 Datasette 的权限文档,以获取有关如何锁定此类访问的更多信息。