You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

django-oauth-toolkit的client_credentials模式验证异常及用户绑定问题

解决django-oauth-toolkit client_credentials模式验证用户并绑定令牌的问题

首先明确:client_credentials模式的标准设计是基于客户端身份授权,默认不会验证用户信息,也不会关联用户到令牌。你遇到的“任意用户名密码都能获取令牌”,是因为这个模式默认忽略用户参数,仅验证客户端的client_id和client_secret。要实现验证合法用户并绑定令牌,需要自定义认证逻辑。

步骤1:自定义ClientCredentials令牌视图

继承默认的ClientCredentialsTokenView,重写用户验证和令牌关联逻辑:

# 你的app/views.py
from django.contrib.auth import authenticate
from django.http import JsonResponse
import json
from oauth2_provider.views import TokenView
from oauth2_provider.models import AccessToken
from rest_framework.exceptions import ValidationError

class CustomClientCredentialsTokenView(TokenView):
    def validate_user(self, request):
        # 从请求体提取用户凭证
        username = request.data.get("username")
        password = request.data.get("password")
        
        # 验证用户合法性
        user = authenticate(username=username, password=password)
        if not user:
            raise ValidationError("用户名或密码无效")
        
        request.user = user
        return super().validate_user(request)

    def create_token_response(self, request):
        response = super().create_token_response(request)
        # 令牌生成后绑定用户
        if response.status_code == 200:
            token_data = json.loads(response.content)
            access_token = AccessToken.objects.get(token=token_data["access_token"])
            access_token.user = request.user
            access_token.save()
        return response

步骤2:替换默认令牌端点路由

在项目urls.py中,替换oauth2的默认令牌路由:

from django.urls import path
from oauth2_provider.views import AuthorizationView
from your_app.views import CustomClientCredentialsTokenView

urlpatterns = [
    # 保留授权页面路由,替换令牌端点
    path('o/token/', CustomClientCredentialsTokenView.as_view(), name="token"),
    path('o/authorize/', AuthorizationView.as_view(), name="authorize"),
]

步骤3:确认客户端配置

在Django后台的Application模型中,确保你的客户端:

  • Authorization grant type勾选了Client credentials
  • 已配置正确的client_id和client_secret

测试验证

发送请求时必须携带完整参数:

curl -X POST -d "grant_type=client_credentials&client_id=你的客户端ID&client_secret=你的客户端密钥&username=合法用户名&password=合法密码" http://你的域名/o/token/
  • 若用户名密码错误,会返回400错误
  • 验证通过后,返回的令牌会在后台AccessToken中关联到对应用户

内容的提问来源于stack exchange,提问作者code writer 3000

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 14:32:37