首页 > 解决方案 > 使用 Flask-Login 认证 Nginx 反向代理

问题描述

我正在实施 Duo Labs 的py_webauthn演示的修改版本,以便向我的网站添加物理身份验证。该演示在 Flask 中构建,并使用该flask-login库与 SQLAlchemy 数据库一起存储用户数据。

理想情况下,我希望 Flask 应用程序充当 Nginx 身份验证器,以便登录用户能够访问proxy_pass服务器上的其他 'ed 服务。

我最初尝试在 Flask 中实现反向代理,但我发现唯一可行的解​​决方案需要 Twisted 框架(因为像 Shellinabox 这样的服务需要不断发出请求),这需要设置一个完全独立的 WSGI 应用程序——这是不必要的很难整合的中间商。

我的理想结果是用户最初访问服务器并被proxy-pass'ed 到 Flask 身份验证服务器,然后能够通过 Nginx 访问其他几个反向代理服务。我仍然对 Python 反向代理持开放态度,但发现 Nginx 最适合我的需求。

我应该如何集成 Flask 和 Nginx?

(演示库的 app.py 文件可在此处获得。Webauthn 功能只是构建在flask-login.)之上。

标签: pythonnginxflasknginx-reverse-proxyflask-login

解决方案


我解决了!可以使用auth_request带有 Flask 的内置 Nginx 作为身份验证器。简单地说,如果 Flask200在被 Nginx 查询时返回 a,Nginx 将允许访问另一个页面。401或者,身份验证器可以返回错误以将用户发送到 Nginx 401 页面(在我的情况下,然后将他们重定向到登录页面)。

要复制,请在 Flask 中添加验证器:

@app.route("/auth")
def nginx_auth():
    if current_user.is_authenticated:
        return "You are logged in! Sweet!"
    else:
        return 'Sorry, but unfortunately you\'re not logged in.', 401

然后,在 Nginx 中,将 anauth_request指向验证器,并将 401 重定向到登录页面。

location /ssh {
   auth_request /auth;
   proxy_pass http://localhost:4200/;
}

location = /auth {
    internal;
    proxy_pass              https://localhost:8081/auth;
    proxy_pass_request_body off;
    proxy_set_header        Content-Length "";
    proxy_set_header        X-Original-URI $request_uri;
}

error_page 401 = @error401;
location @error401 {
    return 302 /login;
}

(代码从Nginx 文档修改。


推荐阅读