【问题标题】:User model other than AUTH_USER_MODEL in Django REST FrameworkDjango REST Framework 中除 AUTH_USER_MODEL 之外的用户模型
【发布时间】:2018-03-16 22:58:25
【问题描述】:

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

Django 具有由模型表示的管理员用户,它或多或少与默认的 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 没有任何连接的模型实例。你们有没有做过类似的事情?

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    嗯,是的,先生。你可以这样做。看下面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 的不同用户模型的身份验证类将完全按照您的方式工作,除了。

    【讨论】:

    • 谢谢,如果您使用这种方法并且它有效,那么我也将使用它:-)
    • @Gal authenticate_credentials 旨在返回一个 (user, token) 的元组,但是您的示例仅返回 True,这真的可行吗? p.s.嘘,你偷了我的答案:(
    【解决方案2】:

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

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

    您的 API 视图应该使用其余框架的设置,而您的 Django 管理员应该使用常规的 django 设置。可能还有其他一些注意事项,但我认为一般情况下你会没事的。

    【讨论】:

      【解决方案3】:

      我立即回想起的一件事是 Mongoengine 如何破解整个 django 身份验证系统。 Mongoengine 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 支持。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-02
        • 1970-01-01
        • 2021-12-23
        • 2016-07-27
        • 1970-01-01
        • 2019-12-10
        相关资源
        最近更新 更多