Flutter调用DRF接口出现Authentication credentials未提供问题排查
问题:登录后Token调用用户信息接口失败,提示认证凭据未提供
我使用Django Rest Framework作为后端、Flutter作为前端开发项目,登录后会获取到格式为{"key":"XXXXXXXXXXXXX"}的Token。测试手动添加Token调用用户信息接口时,持续收到{detail: Authentication credentials were not provided.}错误,Django后台提示Unauthorized: /api/dj-rest-auth/user/,不确定该错误源于DRF配置还是Flutter代码。
相关代码与配置
Flutter代码
Future<User> fetchUser() async { var url = Uri.parse(Config.apiURL + Config.userProfileAPI); print(url); final response = await http.post( url, // headers: { // HttpHeaders.authorizationHeader: // 'Bearer XXXXXXXXXXXXX', headers: { "Authorization": 'JWT XXXXXXXXXXXXX' // 'Authorization: ', },); final responseJson = jsonDecode(response.body); print(responseJson); if (response.statusCode == 200) { return User.fromJson(jsonDecode(response.body)); } else { throw Exception('Failed to load User'); }} class User { int? pk; String? username; User({this.pk, this.username}); User.fromJson(Map<String, dynamic> json) { pk = json['pk']; username = json['username'];} Map<String, dynamic> toJson() { final Map<String, dynamic> data = new Map<String, dynamic>(); data['pk'] = this.pk; data['username'] = this.username; return data;}} class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @override State<HomeScreen> createState() => _HomeScreenState();} class _HomeScreenState extends State<HomeScreen> { late Future<User> futureUser; @override void initState() { super.initState(); futureUser = fetchUser();} @override Widget build(BuildContext context) { return MaterialApp( ......................... FutureBuilder<User>( future: futureUser, builder: (context, snapshot) { if (snapshot.hasData) { return Text(snapshot.data!.username ?? 'noname'); } else if (snapshot.hasError) ; print(snapshot.error); {return Text('${snapshot.error}');} return const CircularProgressIndicator(); },),),],)),),);}}
DRF配置
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.BasicAuthentication', 'rest_framework.authentication.SessionAuthentication', ] } AUTHENTICATION_BACKENDS=['users.models.EmailBackend'] CORS_ALLOW_ALL_ORIGINS=True AllowAny =True
我的问题:登录后为何HttpHeaders.authorizationHeader无效?用户已登录的情况下,是否可直接使用Token获取用户详情?
解决方案
1. DRF配置缺失Token认证类
当前DRF的DEFAULT_AUTHENTICATION_CLASSES只配置了Basic和Session认证,没有启用Token相关的认证类,导致后端无法识别你传入的Token。根据你使用的Token类型修改配置:
- 如果是dj-rest-auth默认的普通Token,添加
rest_framework.authentication.TokenAuthentication:REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.BasicAuthentication', 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.TokenAuthentication', # 新增 ] } - 如果是JWT Token(比如用了
djangorestframework-simplejwt),添加对应的JWT认证类:REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.BasicAuthentication', 'rest_framework.authentication.SessionAuthentication', 'rest_framework_simplejwt.authentication.JWTAuthentication', # 新增 ] }
2. Flutter代码的两个错误
(1)请求方法错误
/api/dj-rest-auth/user/接口默认是GET请求,你当前用了http.post,这会导致接口无法正确处理请求,改成http.get:
final response = await http.get( url, headers: { HttpHeaders.authorizationHeader: 'Token XXXXXXXXXXXXX', // 对应普通Token // 若为JWT则用:HttpHeaders.authorizationHeader: 'Bearer XXXXXXXXXXXXX' }, );
(2)Authorization Header前缀错误
- 普通Token的前缀是
Token,不是JWT; - JWT Token的前缀通常是
Bearer,而非JWT(除非你自定义了认证类的前缀)。
同时推荐使用HttpHeaders.authorizationHeader常量,避免拼写错误。
3. 问题解答
- 为什么
HttpHeaders.authorizationHeader无效?
一是DRF没配置对应的Token认证类,无法识别Token;二是请求方法错误(POST而非GET);三是Header前缀不符合后端要求。 - 用户已登录后能否直接用Token获取用户详情?
可以,只要确保:DRF配置了正确的Token认证类、请求方法为GET、Authorization Header格式正确,就能通过Token获取用户详情。
内容的提问来源于stack exchange,提问作者A_K
相关产品推荐
相关产品推荐

