HTTP Post oAuth 2 "Check the `grant_type` parameter"



我正在使用以下代码在我的dart应用程序中实现维基媒体的OAuth 2授权流:

String jsonString = jsonEncode(<String, String>{
'grant_type' : 'authorization_code',
'redirect_uri' : Uri.encodeFull(redirectUri),
'code' : authCode,
'client_id' : CLIENT_ID,
'client_secret' : clientSecret,
});
String paramName = 'param';
String formBody = paramName + '=' + Uri.encodeQueryComponent(jsonString);
List<int> bodyBytes = utf8.encode(formBody);
Future<http.Response> response = http.post( 
Uri.parse('https://meta.wikimedia.org/w/rest.php/oauth2/access_token'),
headers: <String, String>{
"Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
"Content-Length" : bodyBytes.length.toString()
},
body: bodyBytes,
);

这个的响应是:

{"error";invalid_request", "error_description"缺少必需的参数,包括无效的参数值;包含一个参数多次,或者格式不正确。",
提示": "检查' grant_type '参数", message"缺少必需的参数,包含无效的参数值,不止一次包含一个参数,或者是格式错误的。"}

,这可能与事实content - type仍然是JSON,即使我定义它的头application/x-www-form-urlencoded或因为内容长度是1。

来自Flutter DevTools的头信息

Flutter DevTools的一般信息

为了匹配Content-Type标头,您需要将参数编码为application/x-www-form-urlencoded

要做到这一点,您可以将代码更改为:
String body = Uri(queryParameters: <String, String> {
'grant_type' : 'authorization_code',
'redirect_uri' : Uri.encodeFull(redirectUri),
'code' : authCode,
'client_id' : CLIENT_ID,
'client_secret' : clientSecret,
}).query;

调用几乎相同:

Future<http.Response> response = http.post( 
Uri.parse('https://meta.wikimedia.org/w/rest.php/oauth2/access_token'),
headers: <String, String>{
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
'Content-Length' : body.length.toString()
},  
body: body,
);

附录

这样可以更简洁一些,将这两个部分合并到一个调用中:

Future<http.Response> response = http.post(
Uri.parse('https://meta.wikimedia.org/w/rest.php/oauth2/access_token'),
headers: <String, String>{
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
},  
body: <String, String>{
'grant_type': 'authorization_code',
'redirect_uri': Uri.encodeFull(redirectUri),
'code': authCode,
'client_id': CLIENT_ID,
'client_secret': clientSecret,
}
);

注意,特定的Content-Length报头是不必要的,因为这是在发送时计算的。

相关内容

  • 没有找到相关文章

最新更新