编辑:
后来,在阅读了您的完整问题后,我发现原来的答案不是您想要的。
我已将原版留在此答案的底部供 Google 员工使用,但修订版如下。
Cookie 会自动发送到域中的子域(在大多数现代浏览器中,域名必须包含句点(表示 TLD)才能发生此行为)。身份验证需要作为预处理器进行,并且您的会话需要从集中式源进行管理。让我们来看看吧。
为了确认,我将继续假设(根据您告诉我的)您的设置如下:
- 服务器 1:
- 适用于 domain.com 的 Flask 应用程序
- 服务器 2:
- 用于 username.domain.com 上的用户配置文件的 Flask 应用
首先必须解决的一个问题是将会话存储在两个服务器都可以访问的位置。由于默认会话存储在磁盘上(显然两台服务器不共享同一个硬盘),我们需要对现有设置和新的 Flask 应用程序进行一些修改以用于用户配置文件。
第一步是选择存储会话的位置,由 MySQL、Postgres 等 DBMS 提供支持的数据库是常见的选择,但人们也经常选择将它们放在更短暂的地方,例如 Memcachd 或 Redis例子。
在这两个截然不同的系统之间进行选择的简短版本分为以下几点:
数据库
- 数据库一应俱全
- 您可能已经实现了一个数据库
- 开发人员通常对他们选择的数据库有预先的了解
内存(Redis/Memchachd/等)
- 相当快
- 系统通常提供基本的数据自我管理功能
- 不会对现有数据库产生额外负载
您可以在flask here 和here 中找到一些示例数据库会话。
虽然根据每个用户的体验级别设置 Redis 会更加困难,但我建议使用它。你可以看到一个这样做的例子here。
我认为其余的都包含在原始答案中,其中一部分演示了用户名与数据库记录(较大的代码块)的匹配。
单个 Flask 应用的旧解决方案
首先,您必须设置 Flask 来处理子域,这就像在配置文件中指定新的变量名一样简单。例如,如果您的域是 example.com,您可以将以下内容附加到您的 Flask 配置中。
SERVER_NAME = "example.com"
您可以阅读有关此选项的更多信息here。
这里要注意的一点是,如果您只是在本地主机上工作,这将非常困难(如果不是不可能的话)。如上所述,浏览器通常不会费心将 cookie 发送到名称中没有点(TLD)的域的子域。本地主机也未设置为在许多操作系统中默认允许子域。有一些方法可以做到这一点,比如定义您自己的 DNS 条目,您可以查看这些条目(/etc/hosts 在 *UNIX 上,%system32%/etc/hosts 在 Windows 上)。
准备好配置后,您需要为子域通配符定义 Blueprint。
这很容易做到:
from flask import Blueprint
from flask.ext.login import current_user
# Create our Blueprint
deep_blue = Blueprint("subdomain_routes", __name__, subdomain="<username>")
# Define our route
@deep_blue.route('/')
def user_index(username):
if not current_user.is_authenticated():
# The user needs to log in
return "Please log in"
elif username != current_user.username:
# This is not the correct user.
return "Unauthorized"
# It's the right user!
return "Welcome back!"
这里的技巧是确保您的用户对象的__repr__ 包含用户名键。比如……
class User(db.Model):
username = db.Column(db.String)
def __repr__(self):
return "<User {self.id}, username={self.username}>".format(self=self)
需要注意的是,当用户名包含在 URL 中不起作用的特殊字符(空格、@、? 等)时会出现问题。为此,您需要对用户名实施限制,或者先正确转义名称并在验证时取消转义。
如果您有任何问题或要求,请提出。这是在我喝咖啡休息时间做的,所以有点匆忙。