带自定义用户模型的django-oauth2-provider?

4 投票
4 回答
3536 浏览
提问于 2025-04-18 16:48

我现在在项目中遇到了很大的困难。我正在尝试为我的应用实现Oauth2。我了解到很多关于django-oauth2-provider的信息,并且也尝试过使用它。唯一的问题是,它使用的是django.contrib.auth中的用户模型。而我们网站的主要用户是保存在一个叫做User的自定义模型中,这个模型并没有继承或扩展django.contrib.auth中的模型。

有没有办法让我使用自定义的User模型来创建客户端和令牌呢?

如果django-oauth2-provider不能满足这个需求,有没有人能推荐一些可以与我自己的模型一起实现Oauth2的库呢?

真诚的,

Sushant Karki

4 个回答

0

你需要创建一个自定义的 OAuth2 验证器,并重写 validate_user 这个函数。

"""API Core Auth Utils"""

from django.core.exceptions import ObjectDoesNotExist
from oauth2_provider.oauth2_validators import OAuth2Validator
from rest_framework.request import Request

from core.models import Customer
from core.models.serializers import UserSerializer


class OAuthValidator(OAuth2Validator):  # pylint: disable=abstract-method
    """Custom Validator to be used with OIDC"""

    def get_userinfo_claims(self, request):
        claims = super().get_userinfo_claims(request)
        ...
        return claims

    def get_additional_claims(self, request: Request):
        return {
            "id": request.user.id,
            "email": request.user.email,
            "username": request.user.username,
            "given_name": request.user.first_name,
            "family_name": request.user.last_name,
            "name": f"{request.user.first_name} {request.user.last_name}",
        }


class OAuthCustomerValidator(OAuth2Validator):  # pylint: disable=abstract-method
    """Custom OAuth Validator for Customers to be used with OIDC"""

    def validate_user(self, username, password, client, request, *args, **kwargs):
        try:
            customer = Customer.objects.get(email=username)
            if customer.is_active and customer.authenticate(password):
                request.user = customer
                return True
            return False
        except ObjectDoesNotExist:
            return False

另外,你还可以实现一个请求验证器:from oauthlib.openid import RequestValidator

0

兄弟,我也遇到过同样的问题,我现在很清楚如何用Oauth2做一个自定义用户模型。

现在我使用的是 SimpleJWT 来进行身份验证。

你可以查看这个文档,它会帮助你解决问题,点击这里

1

django-oauth2-provider 这个库会用 settings.AUTH_USER_MODEL 来获取用户模型,如果没有设置的话,它会默认使用 auth.User。如果你扩展了 AbstractUser,那么你的用户模型会包含 auth.User 的所有字段,还可以加上你自己定义的额外字段。

from django.contrib.auth.models import AbstractUser
from django.db import models

class User(AbstractUser):
    some_additional_field = models.BooleanField(default=False)

settings.py 文件中指定要使用的用户模型,方法如下:

AUTH_USER_MODEL = 'user_api.User'

如果你不想基于 AbstractUser 来创建用户模型,你还需要自己写一个用户管理器,比如可以扩展 BaseUserManager

你可以在这里了解更多关于如何自定义 Django 用户模型的信息

5

正如之前的回答所提到的,你应该从 django.contrib.auth.models 中扩展 AbstractUser

提问者提到的访问令牌问题,发生在你在 django-oauth2-provider 迁移之后才更改 AUTH_USER_MODEL 设置的时候。

django-oauth2-provider 迁移时,它会在用户模型和 django-oauth2-provider 之间创建一个关键约束。

解决这个问题的方法很简单:

  1. 创建你新的用户模型,并更改 AUTH_USER_MODEL 设置。
  2. 去你的数据库中的 django_migration 表。
  3. 删除所有与 django-oauth2-provider 相关的行。
  4. 运行 python manage.py makemigrations
  5. 运行 python manage.py migrate

现在,django-oauth2-provider 的表就和正确的用户模型连接起来了。

撰写回答