如何在Flutter中向Django Rest Framework添加用户Token解决禁止访问
解决Flutter携带Token请求Django Rest Framework用户接口的问题
问题背景
在Flutter项目中通过api_service.dart实现登录获取授权Token,但请求dj-rest-auth/user接口时返回Forbidden: /api/dj-rest-auth/user/,同时代码出现类型错误:
error: The element type 'LoginResponseModel' can't be assigned to the map value type 'String'.
错误原因分析
- 请求逻辑颠倒:
fetchUser函数中先发起无授权的GET请求,之后才构造请求头,导致接口无法识别授权信息。 - 请求头格式错误:
Authorization字段直接传入LoginResponseModel对象,而非Django Token认证要求的字符串格式(Token <token_key>)。
修复步骤
1. 从本地缓存获取已保存的Token
登录时已通过SharedService.setLoginDetails保存了LoginResponseModel,需要先取出该模型中的key字段。
2. 构造正确的授权请求头
Django Rest Framework的Token认证要求请求头格式为:
Authorization: Token <你的token值>
3. 修正请求逻辑
先构造包含授权头的请求配置,再发起GET请求。
完整修复代码
修改后的fetchUser函数
Future<User> fetchUser() async { // 1. 从本地获取登录信息 final loginDetails = await SharedService.getLoginDetails(); if (loginDetails == null) { throw Exception('用户未登录'); } // 2. 构造正确的请求头 Map<String, String> requestHeaders = { 'Content-Type': 'application/json', 'Authorization': 'Token ${loginDetails.key}', // 注意格式:Token + 空格 + token值 }; // 3. 发起带授权头的GET请求 var url = Uri.parse(Config.apiURL + Config.userAPI); final response = await http.get(url, headers: requestHeaders); if (response.statusCode == 200) { return User.fromJson(jsonDecode(response.body)); } else if (response.statusCode == 403) { throw Exception('授权失败,请重新登录'); } else { throw Exception('获取用户信息失败,状态码:${response.statusCode}'); } }
补充SharedService的getLoginDetails方法示例
如果还未实现获取登录信息的方法,添加如下代码:
class SharedService { // ... 已有的setLoginDetails方法 ... static Future<LoginResponseModel?> getLoginDetails() async { final prefs = await SharedPreferences.getInstance(); String? loginData = prefs.getString('login_details'); if (loginData != null) { return loginResponseJson(loginData); } return null; } }
关键说明
- 确保
LoginResponseModel类中包含key字段,对应登录接口返回的key值。 - 必须在请求时就携带
Authorization头,不能先发起无授权请求再补头。 - Django端需确保已启用
TokenAuthentication认证方式,并正确配置dj-rest-auth的权限。
内容的提问来源于stack exchange,提问作者A_K
相关产品推荐
相关产品推荐

