我必须用PHP应用程序实现一个向后兼容的Django服务器。遗留应用程序正在使用LegacyUser
模型进行授权,该模型或多或少类似于:
class LegacyUser(models.Model):
id = models.BigAutoField(primary_key=True)
email = models.CharField(max_length=255, unique=True)
password = models.CharField(max_length=120, blank=True, null=True)
...
other_data_fields
...
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
EMAIL_FIELD = 'email'
在新系统中,我不必添加LegacyUser
的新记录(但我可以)。你知道吗
目前,遗留系统不允许每个组创建多个用户。实际上LegacyUser
应该被视为一个组,但我是作为一个用户实现的。你知道吗
现在我必须为每个LegacyUser
实现多个Users
,因此我添加了适当的Django用户进行授权,如:
class User(AbstractUser):
username = None
email = models.EmailField(unique=True)
legacy_user = models.ForeignKey(LegacyUser, on_delete=models.DO_NOTHING)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['publisher']
class Meta:
managed = True
db_table = 'user'
在base.py
设置中:
...
AUTH_USER_MODEL = 'api.LegacyUser'
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=15),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'AUTH_HEADER_TYPES': ('Bearer',),
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'id',
}
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend', #Supports User
'common.auth.backends.LegacyBackend' #Supports LegacyUser
]
...
新的应用程序应该能够同时登录LegacyUser
和User
。授权后LegacyUser.id应该用作用户标识声明。你知道吗
这意味着如果我有一个像:
{
"id": 1,
"email": admin@domain.com,
"password": "hashed_password",
...
}
和两个用户,例如
{
"id": 1,
"email": user1@domain.com,
"password": "hashed_password",
"legacy_user_id": 1,
...
}
{
"id": 2,
"email": user2@domain.com,
"password": "hashed_password",
"legacy_user_id": 1,
...
}
LegacyUser.id
或User.legacy_user.id
的值应该在请求中可见。你知道吗
除此之外,email
字段在LegacyUser
和User
中必须是唯一的
这是否可能有两种用户授权模型?AUTH_USER_MODEL
只能让我有一个这样的模型
AUTH_USER_MODEL = 'api.LegacyUser'
我想到的解决方案(归档向后兼容的应用程序)是将当前密码和电子邮件从LegacyUser
复制到新的User
模型,并将它们标记为最高权限。你知道吗
同步新系统和旧系统的密码也是必须的,这样我就可以使用一些存储过程,在数据库的更新中更改两处的密码?对我来说,它闻起来很难闻,也许有其他方法可以做到这一点,而不同步这些密码或只是使用两个表进行授权?你知道吗
Edit: To solve this issue I have created MySQL view with unified user data needed only for authorization like:
CREATE OR REPLACE VIEW unified_user AS SELECT email as email, password as password, is_active as is_active, last_login as last_login FROM user UNION ALL SELECT email as email, password as password, 1 as is_active, null as last_login FROM legacy_user;
So synchronization of passwords will be done automatically as view will be updated
你想看看[ahttps://docs.djangoproject.com/en/2.2/topics/auth/customizing/。你可以有许多不同的方式来验证你想要的。会话记录中存储的部分信息是成功使用了哪个身份验证后端。这有点牵扯,但他们给你所有必要的控制做几乎任何你喜欢的。你知道吗
几年前,我在一个系统上使用了它,其中主要用户/密码信息来自外部订阅管理服务器。如果user/pass在普通的用户身份验证系统上不起作用,那么我检查了另一个系统。如果成功的话,我会动态地创建一个新用户。你知道吗
您需要一个标志来区分旧用户和新用户的身份验证。 让我集中讨论基于会话的身份验证。你知道吗
]
从中间件中删除它
django.contrib.auth.middleware.AuthenticationMiddleware
,并放置CustomAuthenticationMiddleware。你知道吗在
CustomAuthenticationMiddleware
,根据session变量附加用户。你知道吗为类
CustomUserBackend
实现这些方法。请阅读Auth从视图调用
authenticate
函数(from django.contrib.auth import authenticate
)。你知道吗对于旧用户
对于新用户
我希望这就是你将如何解决基于会话的身份验证问题。如果这起作用;将转向基于令牌的。你知道吗
相关问题 更多 >
编程相关推荐