Django REST Framework中除AUTH_USER_MODEL之外的用户模型

时间:2018-03-16 22:58:25

标签: python django django-rest-framework

我有一个架构问题。我正在使用Django(使用管理面板)和DRF(使用JWT进行无状态身份验证的api)。

Django具有由模型表示的Admin用户,它与默认的Django用户模型大致相同。管理员仅使用Django Admin,不能使用DRF api。

DRF的API用户只允许通过DRF使用api,不能与Django Admin或Django Session等交互。

我知道最好的方法是使用多模型继承,例如:

class User(DjangoUserModel):
    pass

 class Admin(User):
      pass

 class API(User):
      pass

AUTH_USER_MODEL = "User"

但问题是,这些用户完全不同。例如:API用户具有复杂的复合键作为用户名字段,这与简单的Admin用户名字段无法组合。还有很多其他的差异。 ..

问题是:我可以在DRF中使用不是AUTH_USER_MODEL实例的用户对象吗?因此,self.request.user将存储未以AUTH_USER_MODEL以任何方式连接的模型实例。你们有没有做过类似的事情?

3 个答案:

答案 0 :(得分:4)

嗯,是的,先生。你可以做到这一点。请查看以下example

from rest_framework_jwt.authentication import JSONWebTokenAuthentication

class AuthenticatedServiceClient:
    def is_authenticated(self):
        return True

class JwtServiceOnlyAuthentication(JSONWebTokenAuthentication):
    def authenticate_credentials(self, payload):
        # Assign properties from payload to the AuthenticatedServiceClient object if necessary
        return AuthenticatedServiceClient()

在settings.py中:

REST_FRAMEWORK = {
    'UNAUTHENTICATED_USER': None,
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'myapp.authentication.JwtServiceOnlyAuthentication',
    ),
}

如果需要,您可以为DRF定义其他DEFAULT_AUTHENTICATION_CLASSES。身份验证类就像中间件一样,只是一个填充request.user的队列。

使用来自AUTH_USER_MODEL的不同用户模型添加自己的身份验证类将完全按照您的方式工作。

答案 1 :(得分:3)

由于您使用的是Django和DRF,或许您可以编写一个APIUser模型,该模型从AbstractBaseUser扩展到您的自定义项,写一个custom authentication class并将其插入REST_FRAMEWORK.DEFAULT_AUTHENTICATION_CLASSES } 设置。为django admin留下AUTH_USER_MODEL。

您的自定义身份验证可能只需要覆盖authenticate_credentials(我已在DRF github中引用了TokenAuthentication类)并返回APIUser而不是settings.AUTH_USER_MODEL中定义的默认值。这将有点不同,因为您正在解码JWT,因此您可能会从JWT中提取一些信息,并通过您需要的任何方式查找您的APIUser,例如您的复合字段。这应该会导致self.request.user成为DRF API视图的APIUser。

您的API视图应该使用其余框架的设置,而您的Django管理员应该使用常规的django设置。可能还有其他一些注意事项,但我认为通常你会对此感到满意。

答案 2 :(得分:2)

我立即回忆起的一件事是Mongoengine如何破解整个django身份验证系统。 Mongoengine< 0.10有一个django compatibility app,它实现了一个拐杖,用于在MongoDB中存储用户,并通过self.request.user访问它们。

它必须使用拐杖,因为Django Session API是固执己见的,并假设你使用AUTH_USER_MODEL,由SQL数据库支持存储你的用户。

因此,我认为您应该禁用SessionMiddleware和CSRF令牌处理,并为管理员和API目的使用2个不同的custom authentication systems。使用TokenAuthentication或JWTAuthentication,这应该是可行的。

Here's another example of a project使用DRF和Mongoengine,custom implementation of TokenAuthentication,由MongoDB支持。