Skip to content

The Untappd provider sends token request parameters in both the query string and the request form #688

Description

@kevinchalet

The Untappd provider uses GET requests and sends the token request parameters in both the query string and the request form using formurl-encoding, which is a strong sign something is not right as GET requests are not expected to have a content attached (.NET Core's HttpClient allows it, but on .NET Framework, the following code would throw an exception:)

protected override async Task<OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context)
{
var tokenRequestParameters = new Dictionary<string, string>()
{
["client_id"] = Options.ClientId,
["redirect_uri"] = context.RedirectUri,
["client_secret"] = Options.ClientSecret,
["code"] = context.Code,
["grant_type"] = "authorization_code",
};
// PKCE https://tools.ietf.org/html/rfc7636#section-4.5, see BuildChallengeUrl
if (context.Properties.Items.TryGetValue(OAuthConstants.CodeVerifierKey, out var codeVerifier))
{
tokenRequestParameters.Add(OAuthConstants.CodeVerifierKey, codeVerifier!);
context.Properties.Items.Remove(OAuthConstants.CodeVerifierKey);
}
var parameters = new Dictionary<string, string?>
{
["client_id"] = Options.ClientId,
["redirect_uri"] = context.RedirectUri,
["client_secret"] = Options.ClientSecret,
["code"] = context.Code,
};
var address = QueryHelpers.AddQueryString(Options.TokenEndpoint, parameters);
using var requestContent = new FormUrlEncodedContent(tokenRequestParameters);
using var requestMessage = new HttpRequestMessage(HttpMethod.Get, address);
requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
requestMessage.Content = requestContent;
requestMessage.Version = Backchannel.DefaultRequestVersion;
using var response = await Backchannel.SendAsync(requestMessage, Context.RequestAborted);
if (response.IsSuccessStatusCode)
{
var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync(Context.RequestAborted));
return OAuthTokenResponse.Success(payload);
}
else
{
await Log.ExchangeCodeErrorAsync(Logger, response, Context.RequestAborted);
throw new HttpRequestException("An error occurred while exchanging token codes.");
}
}

We should determine whether this monstrosity is 100% required or remove the request form part if it's not.

/cc @martincostello

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions