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
相关产品推荐
相关产品推荐

