使用Postman测试Django+Angular项目登录时提示未提供认证凭证
嘿,我帮你梳理下这个问题的根源和解决办法——你用Postman测登录接口时拿到"detail": "Authentication credentials were not provided."的错误,主要是路由顺序和权限配置的问题,咱们一步步来:
问题1:路由顺序导致登录接口根本没被命中
看你的urls.py,最上面的url(r'^', TemplateView.as_view(...))是匹配所有路径的通配路由,Django路由是从上到下匹配的,第一个匹配到就直接返回了,所以你的api-login-user、auth/这些具体API路由根本没机会被执行!你的登录请求其实都被导向了Angular的模板页,自然会触发权限校验错误。
问题2:权限配置冲突
你的settings.py里DEFAULT_PERMISSION_CLASSES同时加了AllowAny、IsAuthenticated、IsAdminUser,REST framework的权限类是全部满足才允许访问,这就矛盾了——哪怕你想让登录接口允许匿名访问,IsAuthenticated也会强制要求用户必须已登录,直接触发凭证缺失的错误。
修复步骤
1. 调整路由顺序,把通配路由放最后
修改urls.py,把最宽泛的r'^'路由挪到所有具体API路由的后面,这样具体接口能先被匹配:
urlpatterns = [ url(r'^api-login-user$', views.LoginUserView.as_view()), url(r'^auth/', ObtainAuthToken.as_view()), path('api-auth/', include('rest_framework.urls', namespace='rest_framework')), url(r'^', include(router.urls)), # 把Angular的模板路由放到最后,只匹配其他路由都没命中的情况 url(r'^', TemplateView.as_view(template_name='angular/index.html')), ]
2. 修正权限配置,避免冲突
两种可选方案:
方案A:全局允许匿名访问,其他接口单独加权限
修改settings.py的REST_FRAMEWORK配置,全局只保留AllowAny,后续需要登录的接口再单独配置IsAuthenticated:
REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.AllowAny', ], 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.BasicAuthentication', 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.TokenAuthentication', 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', ], 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', }
方案B:全局要求登录,给登录接口单独开权限
如果你的大部分接口都需要登录,那给LoginUserView单独配置AllowAny权限,这样它就能被匿名访问:
from rest_framework.permissions import AllowAny class LoginUserView(APIView): # 给这个接口单独设置允许匿名访问 permission_classes = [AllowAny] def post(self, request, *args, **kwargs): username = request.data.get('username') password = request.data.get('password') user = authenticate(username=username, password=password) if user: payload = jwt_payload_handler(user) token = { 'token': jwt.encode(payload, SECRET_KEY), 'status': 'success' } return Response(token) else: return Response( {'error': 'Invalid credentials', 'status': 'failed'}, )
3. Postman测试的小细节
- 确保请求方法是
POST,URL正确(比如http://localhost:8000/api-login-user) - 请求体用
form-data或者raw(JSON)格式传递username和password参数 - 如果之前请求带过
Authorization头,记得清空,登录接口不需要带token访问
内容的提问来源于stack exchange,提问作者jim root

