繁体   English   中英

跨多个Django站点的Django一个用户

[英]Django one user across multiple django sites

我有一个情况,我有三个站点A,B,C。 A更多是管理站点,B和C是面向消费者的应用程序。 他们每个人都有各自独立的数据库。 我现在想做的如下:

我希望所有三个A,B,C都以这样的方式连接:当新用户在B上注册并且注册成功时,同一用户应该能够登录A或C。如果用户有任何更改,它们也会反映在A和C上。

到目前为止,我认为解决方案是:

当用户在B处注册时,我可以使用相同的凭据在A和C上复制用户,因此这将允许用户登录这三个站点中的任何一个。 我也在考虑拥有一个中央数据库来存储Django身份验证模型的想法,但是我不确定那种情况下身份验证将如何工作。

我需要有关如何完成此操作的建议。 此外,这是否有资格被称为SSO?

如果有人发现问题是误导性的,模糊的或不适当的,请在投票之前提及原因

您的问题有两种解决方案:

  1. 使用路由到多个数据库。 Django支持不同模型的不同数据库(有关更多信息,请参见@ https://docs.djangoproject.com/en/1.8/topics/db/multi-db/ )。 因此,您可以将针对身份验证模型的所有查询路由到身份验证数据库。 Django文档已经提供了这样的配置@ https://docs.djangoproject.com/en/1.8/topics/db/multi-db/#an-example 我没有测试这种配置然而,这将能够使用外键到用户模式的问题(因为它会被存储在不同的数据库)。 要解决此问题,您可以在所有项目中都有一个UserProxy模型(或类似名称的模型),该模型将仅保留User的用户名,以便您能够创建从模型到UserProxy的外键关系。 UserProxy将把需要检索的任何用户数据转发到正确的User对象。

  2. 使用Django身份验证。 可以将Django配置为使用多种不同的身份验证方法(请检查docs @ https://docs.djangoproject.com/en/1.8/topics/auth/customizing/ )。 对于站点B和C,您可以配置使用管理站点(A)的数据库登录的身份验证后端。 我正在成功使用此方法-在这里您可以做到这一点:

class RegUsrBackend(django.contrib.auth.backends.ModelBackend):
    def authenticate(self, username=None, password=None):

        try:
            conn = django.db.connections['users']
            cursor = conn.cursor()

            cursor.execute("select pn.password, pn.username, au.first_name, au.last_name from auth_user au where au.username = %s ", [username])
            row = cursor.fetchone()
            if row and check_password(password, row[0]):
                user, created = get_user_model().objects.get_or_create(username = row[1] )
                if user.first_name != row[2] or user.last_name != row[3] :
                    user.first_name = row[2]
                    user.last_name = row[3]
                    user.set_unusable_password()
                    user.save()
                return user
        except:
            return None

如您所见,在这里我还配置了一个不同的users数据库(名为users ),并向该数据库发出原始查询,以获取具有传递的用户名及其密码哈希的用户。 之后,我检查用户是否存在并具有正确的密码(使用check_password),如果一切都检查了,我使用get_or_create来检索或创建该用户的本地实例(即应用程序数据库中的用户实例)。 。 最后,在返回用户之前,我先检查他的名字或姓氏是否对管理应用程序有所更改,然后在本地对其进行更新。

最后,您需要将此后端放入使用它的应用程序的AUTHENTICATION_BACKENDS设置中。

使用这种方法,您将不必使用任何UserProxy来支持外键(因为将存在本地User模型),但是我觉得它比第一种方法更糟糕。 另外,如果用户的详细信息已在管理数据库中更改,则其他用户的详细信息将在他登录时更新。此外,您还可以将后端更改为更特殊的内容,例如,而不是查询您可以创建的数据库您的管理后端中的REST api,并使用它来登录其他应用程序。

最后,为了回答您有关SSO的问题,我上面描述的不是SSO。 SSO意味着,当用户登录到一个站点时,他无需再次登录其他站点,只要在所有这些站点中保留并共享一个会话密钥即可。 SSO的常见解决方案是使用CAS( http://jasig.github.io/cas/4.1.x/index.html ),但是我对此没有很好的经验(并且您还需要另外一个 ,基于Java的服务器来托管CAS)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM