Django后端+Flutter前端POST请求遇认证凭证缺失问题求助
Flutter向Django POST数据时提示"Authentication credentials were not provided"的解决方法
问题背景
基于Django后端、Flutter前端开发项目,从Flutter UI通过REST API向Django数据库提交POST请求时,持续收到错误:
"detail": "Authentication credentials were not provided."
但通过Web浏览器发送相同的POST请求却能正常执行,核心原因是Flutter端未携带认证信息导致权限校验失败。
相关代码
Flutter端提交请求代码
Future<CreateProduct> submitProduct(String name , String price , String brand , String countinstock , String category , String description) async { String createProductUri = "http://127.0.0.1:8000/api/products/create/"; final response = await http.post(Uri.parse(createProductUri),body: { "name": name, "price": price, "brand": brand, "countInStock": countinstock, "category": category, "description": description }); if (response.statusCode == 201){ final responseString = response.body; return createProductFromJson(responseString); } }
Django端视图代码
@api_view(['POST']) @permission_classes([IsAdminUser]) def createProduct(request): user = request.user data = request.data product = Product.objects.create( user=user, name=data['name'], price=data['price'], brand=data['brand'], countInStock=data['countInStock'], category=data['category'], description=data['description'], ) serializer = ProductSerializer(product, many=False) return Response(serializer.data)
问题原因
Django视图添加了@permission_classes([IsAdminUser])权限控制,要求请求必须来自已认证的管理员用户。浏览器能正常工作是因为已通过Django后台登录,浏览器自动保存并携带了session cookie作为认证凭据;而Flutter的HTTP请求默认不会自动携带这些认证信息,因此被权限拦截。
解决方案
方案1:使用Session认证(复用浏览器登录态)
如果开发环境中Flutter与Django已配置跨域支持,可让Flutter请求携带session cookie:
- 修改Flutter请求代码,添加
withCredentials: true并指定Content-Type:
Future<CreateProduct> submitProduct(String name , String price , String brand , String countinstock , String category , String description) async { String createProductUri = "http://127.0.0.1:8000/api/products/create/"; final response = await http.post( Uri.parse(createProductUri), body: { "name": name, "price": price, "brand": brand, "countInStock": countinstock, "category": category, "description": description }, headers: { "Content-Type": "application/x-www-form-urlencoded", }, withCredentials: true, ); if (response.statusCode == 201){ final responseString = response.body; return createProductFromJson(responseString); } else { print(response.body); throw Exception("提交产品失败"); } }
- 配置Django跨域支持(若存在跨域):
安装django-cors-headers后,在settings.py中添加以下配置:
INSTALLED_APPS = [ # ... 其他已安装应用 'corsheaders', ] MIDDLEWARE = [ # ... 其他中间件 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', ] # 允许携带认证凭据 CORS_ALLOW_CREDENTIALS = True # 允许Flutter运行的地址,根据实际情况调整 CORS_ALLOWED_ORIGINS = [ "http://127.0.0.1:5500", "http://localhost:5500", ]
方案2:使用Token认证(更适合前后端分离场景)
Django REST Framework的Token认证更适配前后端分离架构:
- 启用Token认证:
在settings.py中添加配置:
INSTALLED_APPS = [ # ... 其他已安装应用 'rest_framework.authtoken', ] REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.TokenAuthentication', ], }
- 生成管理员用户的Token:
通过命令行生成:
python manage.py drf_create_token <你的管理员用户名>
或在Django后台的Token管理页面创建。
3. 修改Flutter请求,在请求头中携带Token:
Future<CreateProduct> submitProduct(String name , String price , String brand , String countinstock , String category , String description) async { String createProductUri = "http://127.0.0.1:8000/api/products/create/"; // 替换为你的管理员用户Token String authToken = "生成的Token值"; final response = await http.post( Uri.parse(createProductUri), body: { "name": name, "price": price, "brand": brand, "countInStock": countinstock, "category": category, "description": description }, headers: { "Authorization": "Token $authToken", "Content-Type": "application/x-www-form-urlencoded", }, ); if (response.statusCode == 201){ final responseString = response.body; return createProductFromJson(responseString); } else { print(response.body); throw Exception("提交产品失败"); } }
内容的提问来源于stack exchange,提问作者HubTech Softwares
相关产品推荐
相关产品推荐

