HTTP Post oAuth 2 "Check the `grant_type` parameter"
To match the Content-Type
header, you'll need to encode the parameters as application/x-www-form-urlencoded
.
To do this, you can change your code to something like:
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;
The invocation is pretty much the same:
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,
);
Addendum
This can be a bit cleaner, combining both parts into the one invocation:
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,
}
);
Note that the specific Content-Length
header is not necessary, as this is calculated on send.
underwhelmingToaster
Updated on January 01, 2023Comments
-
underwhelmingToaster over 1 year
I am implementing the OAuth 2 authorization flow for Wikimedia in my dart app using the following code:
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, );
The response for this is:
{ "error": "invalid_request", "error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.",
"hint": "Check the `grant_type` parameter", "message": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed." }It might have to do with the fact that the content-type is still JSON, even though I defined it in the header as
application/x-www-form-urlencoded
or because the content-length is -1. -
underwhelmingToaster over 2 yearsThis still suffers excactly the same problems, only difference is the body is not utf-8 encoded.
-
msbit over 2 yearsInteresting. I don't have the appropriate client id etc, but running your code gives me the error provided, whereas running mine gives a different error:
{"error":"invalid_client","error_description":"Client authentication failed","message":"Client authentication failed"}
which I more or less expected. -
underwhelmingToaster over 2 yearsI removed the Content Lenght Params as in your edit (and removed the redirect uri as it is not required) and now it works. Thanks!