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

DRF中UserActivation ApiView调用报错:未提供认证凭证

问题描述

我编写了一个用于激活用户的UserActivationView(继承自APIView):

class UserActivationView(APIView):
    authentication_classes = ([])
    permission_classes = [AllowAny]
    """ 
    Intermediate view to activate a user's email. 
    """
    def get (self, request, uid, token):
        protocol = 'https://' if request.is_secure() else 'http://'
        web_url = protocol + request.get_host()
        post_url = web_url + "/auth/users/activate/"
        post_data = {'uid': uid, 'token': token}
        result = requests.post(post_url, data = post_data)
        content = result.text
        return Response(content)

通过Djoser发送邮件中的链接访问该视图时,返回以下错误:

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

"{"detail":"Authentication credentials were not provided."}

相关配置如下:

用户应用路由

path('activate-user/<str:uid>/<str:token>/',  views.UserActivationView.as_view()),

全局URL配置

# Register API
apipatterns = [
    path('', include('activities.urls')),
    path('', include('social_auth.urls')),
    path('', include('users.urls')),
]

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/v1/', include(apipatterns)),
    path('auth/', include('djoser.urls')),
    path('auth-token/', include('djoser.urls.authtoken')),
    re_path(r'^$', views.index, name='index'),

]

DRF配置

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
        'rest_framework.permissions.AllowAny',
    ],
    'DEFAULT_FILTER_BACKENDS': (
        'django_filters.rest_framework.DjangoFilterBackend',
    ),
}

请问该如何解决这个认证错误?


解决方案

1. 修正全局DRF权限配置

你的全局DEFAULT_PERMISSION_CLASSES同时配置了IsAuthenticated和AllowAny,DRF会要求用户满足所有权限类的要求,这就导致匿名用户无法通过IsAuthenticated的检查,进而拦截了Djoser的激活接口(本应允许匿名访问)。

修改DRF配置,移除矛盾的权限类:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],
    'DEFAULT_FILTER_BACKENDS': (
        'django_filters.rest_framework.DjangoFilterBackend',
    ),
}

2. 明确配置Djoser的匿名权限

在settings.py中添加Djoser配置,确保激活等需要匿名访问的接口权限正确:

DJOSER = {
    'ACTIVATION_URL': 'activate-user/{uid}/{token}/',
    'PERMISSIONS': {
        'activation': ['rest_framework.permissions.AllowAny'],
        'password_reset': ['rest_framework.permissions.AllowAny'],
        'password_reset_confirm': ['rest_framework.permissions.AllowAny'],
        'user_create': ['rest_framework.permissions.AllowAny'],
        'token_create': ['rest_framework.permissions.AllowAny'],
        # 其他需要认证的接口保持默认配置
        'set_password': ['rest_framework.permissions.IsAuthenticated'],
        'user_delete': ['rest_framework.permissions.IsAuthenticated'],
    }
}

3. 优化UserActivationView逻辑(可选但推荐)

无需通过外部HTTP请求调用Djoser接口,直接复用Djoser的激活逻辑更高效可靠:

from djoser.views import ActivationView
from rest_framework.response import Response

class UserActivationView(APIView):
    authentication_classes = []
    permission_classes = [AllowAny]

    def get(self, request, uid, token):
        # 复用Djoser的激活视图逻辑
        activation_view = ActivationView.as_view()
        # 构造POST请求对象
        post_request = request._request
        post_request.method = 'POST'
        post_request.POST = {'uid': uid, 'token': token}
        # 调用激活逻辑并返回结果
        response = activation_view(post_request)
        return Response(response.data, status=response.status_code)

4. 验证路由匹配

确保Djoser的ACTIVATION_URL配置与你的用户应用路由完全一致,避免链接跳转错误。

完成以上配置后,再次访问邮件中的激活链接即可正常完成用户激活,不会再出现认证错误。

内容的提问来源于stack exchange,提问作者B. Mohammad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 06:17:38