跳转到主要内容

基于现有域名cookie进行用户认证的Datasette插件

项目描述

datasette-auth-existing-cookies

PyPI CircleCI License

基于现有域名cookie进行用户认证的Datasette插件。

何时使用此插件

当您在与其他已认证网站同一域名上托管Datasette实例时,此插件允许您为Datasette构建自定义认证。

考虑一个位于www.example.com的网站,它支持用户认证。

您可以在data.example.com上运行Datasette,以便它可以看到为.example.com域名设置的cookie。

使用此插件,您可以在www.example.com/user-for-cookies上构建一个API端点,该端点根据用户的cookie返回表示当前已登录用户的JSON对象。

该插件可以通过将这些cookie传递到API并查看用户是否应登录来保护对任何data.example.com页面的访问。

您还可以使用子类化来使用某些其他机制解码现有的cookie。

配置

此插件需要在Datasette的metadata.json文件中进行一些配置。

它需要知道以下信息

  • 应该注意哪些域名cookie?如果您正在针对Dango进行认证,这可能是["sessionid"]
  • 它可以将传入的cookie发送到哪个API,该API可以将它们解码为一些用户信息?
  • 如果用户需要登录,它应该将用户重定向到哪里?

以下配置设置了这三个值

{
    "plugins": {
        "datasette-auth-existing-cookies": {
            "api_url": "http://www.example.com/user-from-cookies",
            "auth_redirect_url": "http://www.example.com/login",
            "original_cookies": ["sessionid"]
        }
    }
}

使用此配置,用户的当前sessionidcookie将作为常规cookie头传递到API URL。

您可以使用"headers_to_forward"配置选项指定应转发到api_url的请求中的额外头信息列表。例如,如果您将以下内容添加到上述配置中

            "headers_to_forward": ["host", "x-forwarded-for"]

那么对https://data.example.com/的访问将执行以下API调用

http://www.example.com/user-from-cookies?host=data.example.com&x-forwarded-for=64.18.15.255

API URL应返回一个空JSON对象,如果用户当前未登录

{}

或者返回一个表示用户的JSON对象,如果他们已经登录

{
    "id": 123,
    "username": "simonw"
}

该对象可以包含您喜欢的任何键 - 信息将被存储在新签名的cookie中,并以"auth"字典的形式在ASGI的scope中提供给Datasette代码。

建议至少包括一个id和一个username

模板

您可能希望让用户知道他们已经登录。该插件直接将上面的auth数据提供给Datasette模板。您可以使用自定义的base.html模板(请参阅模板文档),如下所示

{% extends "default:base.html" %}

{% block extra_head %}
<style type="text/css">
.hd .logout {
    float: right;
    text-align: right;
    padding-left: 1em;
}
</style>
{% endblock %}

{% block nav %}
    {{ super() }}
    {% if auth and auth.username %}
        <p class="logout">
            <strong>{{ auth.username }}</strong> &middot; <a href="https://www.example.com/logout">Log out</a>
        </p>
    {% endif %}
{% endblock %}

其他选项

  • require_auth。默认为True。如果您想允许未经身份验证的用户查看Datasette实例,可以将它设置为False
  • cookie_secret。您可以使用它来设置由该插件设置的cookie所使用的签名密钥(您应该使用密钥配置值)。如果您没有设置密钥,该插件将在首次运行时创建一个,并根据您的操作系统将其存储在适当的状态目录中(根据appdirs,为user_state_dir)。
  • cookie_ttl。插件设置自己的cookie以避免每次接收到请求时都调用后端API。默认情况下,它仍然最多每10秒调用API一次,以防用户在主网站上注销。您可以使用此设置提高或降低超时时间。
  • trust_x_forwarded_proto。如果您在代理后面运行,该代理为您添加HTTPS支持,您可能会发现插件错误地构建了带有不正确方案的?next= URL。如果您知道您的代理发送了x-forwarded-proto头(您可以使用datasette-debug-asgi插件来调查此问题),将trust_x_forwarded_proto选项设置为True将导致插件信任该头。
  • next_secret。请见下文。

登录重定向机制

如果用户没有有效的身份验证cookie,他们将被重定向到现有的登录页面。

该页面使用auth_redirect_url设置指定。

根据上述示例配置,用户登录后应发送到的URL将作为该页面的?next=参数指定,例如

http://www.example.com/login?next=http://foo.example.com/

您需要编程登录端点,以便它不会受到未验证的重定向漏洞的影响。

一种方法是通过验证传递给?next=的URL是属于受信任网站的URL。Django自己的登录视图就是这样做的,通过验证URL的主机名是否在批准的列表中。

另一种方法是使用next_secret配置参数为此URL设置一个签名密钥。此签名密钥将用于使用Python itsdangerous模块构建一个?next_sig=签名令牌,如下所示

?next_sig=Imh0dHBzOi8vZGVtby5leGFtcGxlLmNvbS9mb28vYmFyIg.7JdhRCoP7Ow1cRF1ZVengC-qk6c

您应使用Datasette的密钥配置值机制,从环境变量中设置此密钥,如下所示

{
    "plugins": {
        "datasette-auth-existing-cookies": {
            "api_url": "http://www.example.com/user-from-cookies",
            "auth_redirect_url": "http://www.example.com/login",
            "original_cookies": ["sessionid"],
            "next_secret":  {
                "$env": "NEXT_SECRET"
            }
        }
    }
}

您可以在自己的登录表单的Python代码中这样验证此密钥

from itsdangerous import URLSafeSerializer, BadSignature

def verify_next_sig(next_sig):
    signer = URLSafeSerializer(next_secret)
    try:
        decoded = signer.loads(next_sig)
        return True
    except BadSignature:
        return False

如果您想在这里实现自己的签名机制,可以通过扩展ExistingCookiesAuth并重写build_auth_redirect(next_url)方法来实现。

权限

如果当前用户已登录但不应有权访问Datasette实例,您可以通过API返回以下内容来表示

{
    "forbidden": "You do not have permission to access this page."
}

键必须是"forbidden"。值可以是任何字符串,它将被显示给用户。

这在处理多个不同的子域时特别有用。您可能会收到以下API调用

http://www.example.com/user-from-cookies?host=a-team.example.com

您可以检查基于用户cookie的认证用户是否有权访问a-team Datasette实例,如果他们不应能查看它,则返回一个"forbidden" JSON对象。

如果用户被允许访问Datasette(因为API以JSON形式返回了他们的用户身份),则插件将在该子域上设置一个cookie,授予他们访问权限。

此cookie默认在十秒后过期。这意味着如果用户因任何原因被移除权限,他们仍将有最多十秒的时间继续访问Datasette。如果您不能接受这一点,可以使用cookie_ttl设置来减少此超时,但这将增加更频繁的API调用以检查用户权限的次数。

项目详情


下载文件

下载您平台上的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源代码分发

此版本没有可用的源代码分发文件。请参阅生成分发存档的教程

构建分发

datasette_auth_existing_cookies-0.7-py3-none-any.whl (13.6 kB 查看哈希值)

上传时间 Python 3

支持者

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页