此问题的两个答案,取决于是否跨不同网站或不同子域进行共享第二个答案:Multiple Django apps, shared authentication
用户访问site1.com并登录。现在,如果他访问site2.com,那么他应该已经在该站点登录(已验证)。
site1.com和site2.com由同一服务器上的不同Django应用程序处理。
我知道网站可以共享包含身份验证表的数据库。我没有得到的是如何处理会话数据。登录到site1后,用户转到site2。在这里,他总是有request.user =“AnonymousUser:AnonymousUser”而不是user_id。
我已将其设置为:https://docs.djangoproject.com/en/dev/topics/db/multi-db/:
site1的设置包含一个包含auth模型以及其他一些数据表的数据库。 site2的设置有2个数据库。一个有自己的数据表,也有user1使用的数据表。我基本上复制了类AuthRouter并设置了数据库路由器。
我想要做的不可能吗?我实际上并不了解两个站点如何共享会话数据。在Django之外我需要一些特别的东西吗?或者这应该工作?我可以在这里包含我的代码,但如果我对此的基本思考是错误的,不要混淆问题。
编辑:这是我的设置。我在localhost上尝试这个。
Site1在localhost上运行:8080
site2在localhost:8000
上运行第2页APP:
db_router.py:
class AuthRouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label == 'auth':
return 'the_ui'
return None
# same for write
def allow_syncdb(self, db, model):
if db == 'the_ui':
return model._meta.app_label == 'auth'
elif model._meta.app_label == 'auth':
return False
return None
class OtherRouter(object):
def db_for_read(self, model, **hints):
return "default"
# same for write, relation, syncdb
settings.py:
DATABASE_ROUTERS = ['site2_app.db_router.AuthRouter', 'site2_app.db_router.OtherRouter']
SESSION_COOKIE_DOMAIN = 'http://localhost:8080'
SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"
DATABASES = {
'default': {
# ...
},
'the_ui': {
# ...
}
}
第1页APP:
# no router
# only single database, same as the "the_ui" used in site2
SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"
答案 0 :(得分:14)
根据使用不同网站的初始问题,标记的答案是正确的。
以下是不同子域的答案,例如www.site.com和shop.site.com
使用问题中描述的共享数据库身份验证。然后,在两个settings.py中:
SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"
SESSION_COOKIE_DOMAIN = '.site.com' #notice the period
SESSION_COOKIE_NAME = 'my_cookie'
SECRET_KEY = "" the same in both settings.py
如果您有其他不应共享此信息的子域,可能会出现一些问题。或者,也许不是,如果你给他们的饼干不同的名字??
不确定这是否适用于localhost。
答案 1 :(得分:3)
正如您所说,这两个站点可以通过共享数据库或在各自的数据库之间同步Users表来拥有相同的身份验证数据。
这将确保site1.com的任何用户自动成为site2.com的成员,反之亦然。
但您对登录site1.com的任何用户的要求应该自动登录site2.com有点棘手。你真正需要的是Single Sign On (SSO).
仅仅共享数据库(包括会话数据)无法实现的原因是因为跨域问题。
使用Django有许多SSO解决方案。看看this SO问题。虽然我从未使用它,Django-openid似乎是个不错的选择。
答案 2 :(得分:0)
您可以使用database routers指定哪个数据库应该用于auth后端。
这里我给出了一个示例路由器代码:
class UserSessionRouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label == 'auth':
return 'usersandsessions'
elif model._meta.app_label == 'accounts':
return 'usersandsessions'
elif model._meta.app_label == 'sessions':
return 'usersandsessions'
return None
def db_for_write(self, model, **hints):
if model._meta.app_label == 'auth':
return 'usersandsessions'
elif model._meta.app_label == 'accounts':
return 'usersandsessions'
elif model._meta.app_label == 'sessions':
return 'usersandsessions'
return None
然后使用数据库设置DATABASE_ROUTERS和SESSION_COOKIE_DOMAIN指定路由器,如下所示
DATABASE_ROUTERS = ['site2.routers.UserSessionRouter']
SESSION_COOKIE_DOMAIN = 'site1.com'
答案 3 :(得分:-1)
正如Sudipta所说,openid是实现SSO的一种方式。
另一种方法是直接使用SAML(有一些工具用于此),或者像Stormpath(https://stormpath.com)这样的托管服务为你做SSO的东西,并直接支持Django的auth系统: https://github.com/stormpath/stormpath-django
我在Stormpath工作,非常有偏见,但我认为我会因为关于SSO + Django解决方案存在很多混淆而引起注意。