首页 文章

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

提问于
浏览
8

我有一个架构问题 . 我正在使用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 回答

  • 2

    嗯,是的,先生 . 你可以做到这一点 . 请看以下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 添加使用不同用户模型的自己的身份验证类将完全按照您的方式工作 .

  • 4

    由于您使用的是Django和DRF,也许您可以编写 APIUser 模型,该模型从AbstractBaseUser扩展到您的自定义,编写custom authentication class并将其插入REST_FRAMEWORK.DEFAULT_AUTHENTICATION_CLASSES设置 . 为django管理员单独留下AUTH_USER_MODEL .

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

    你的API视图应该使用其余框架的设置,你的Django管理员应该使用常规的django设置 . 可能还有其他一些注意事项,但一般来说,我认为你会这样做 .

  • 3

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

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

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

    Here's another example of a project与DRF和Mongoengine,custom implementation of TokenAuthentication,由MongoDB支持 .

相关问题