Postman请求Django OAuth2正常,Axios报unsupported_grant_type错误
排查Axios请求Django OAuth2接口返回
unsupported_grant_type的问题 核心原因
django-oauth-toolkit的/o/token/接口仅支持**application/x-www-form-urlencoded**格式的请求体,而Axios默认会将JavaScript对象序列化为JSON格式发送(同时自动设置Content-Type: application/json),这种格式后端无法正确解析grant_type参数,因此返回unsupported_grant_type错误。
Postman能成功是因为默认发送token请求时,使用的是form-data或x-www-form-urlencoded格式,这两种格式都能被后端正确识别。
修复方案
方案1:使用URLSearchParams构造请求体
直接用React Native内置的URLSearchParams来构造符合要求的请求体,Axios会自动适配正确的请求头:
import axios from 'axios'; const fetchOAuthToken = async () => { try { const formData = new URLSearchParams(); // 根据你的授权类型填写参数,示例为password模式 formData.append('grant_type', 'password'); formData.append('username', '你的用户名'); formData.append('password', '你的密码'); formData.append('client_id', '你的客户端ID'); formData.append('client_secret', '你的客户端密钥'); // 仅适用于保密客户端 const response = await axios.post('/o/token/', formData); console.log('获取令牌成功:', response.data); } catch (err) { console.error('请求失败:', err.response.data); } };
注:如果需要手动指定请求头,可在Axios配置中添加
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },但URLSearchParams会自动触发这个设置,通常无需额外配置。
方案2:使用qs库序列化请求体
如果你的项目已经依赖了qs库(常用于处理URL编码),可以用它来序列化参数:
import axios from 'axios'; import qs from 'qs'; const fetchOAuthToken = async () => { try { const params = { grant_type: 'password', username: '你的用户名', password: '你的密码', client_id: '你的客户端ID', client_secret: '你的客户端密钥' }; const response = await axios.post('/o/token/', qs.stringify(params), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }); console.log('获取令牌成功:', response.data); } catch (err) { console.error('请求失败:', err.response.data); } };
常见排查点
- 确认
grant_type拼写完全正确(大小写敏感,比如password不能写成Password) - 检查客户端ID、密钥是否与Postman中使用的一致
- 若使用
client_credentials模式,确保后端已将客户端配置为允许该授权类型 - 不要直接传递JSON对象作为请求体(比如
axios.post('/o/token/', { grant_type: 'password' })),这是最容易踩的坑
内容的提问来源于stack exchange,提问作者code writer 3000
相关产品推荐
相关产品推荐

