I really been struggling with exchanging the code received from Xero after a user from another Xero organisation has authorised my app.
Whatever I tried I consistently receive a 400 - Bad Request, For obvious security reasons "Bad Request" is all the information in the response.
I have tried using StringContent
. Setting the accept headers of the HttpClient
. Using httpClient.PostAsync()
.
Here's the what the request headers and body need to contain:
POST https://identity.xero.com/connect/token
authorization: "Basic " + base64encode(client_id + ":" + client_secret)
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=xxxxxx
&redirect_uri=https://myapp.com/redirect
where xxxxx is the code returned to the callback method.
Below is the the method in my service which handles the App authorisation callback. I'd be super appreciative if someone could point out what I'm not doing right.
public async Task<string> AuthoriseApp(string code, string state)
{
try
{
var clientState = TokenUtilities.GetCurrentState();
if (state != clientState)
{
return "Cross site forgery attack detected!";
}
var paramss = new Dictionary<string, string>
{
{ "grant_type", "authorization_code" },
{ "code", code },
{ "redirect_uri", xeroConfig.CallbackUri.AbsoluteUri }
};
var body = new FormUrlEncodedContent(paramss);
var httpClient = new HttpClient();
using var requestMessage = new HttpRequestMessage(HttpMethod.Post, xeroConfig.XeroIdentityBaseUri + "/connect/token")
{
Content = body
};
requestMessage.Headers.Authorization = new BasicAuthenticationHeaderValue(xeroConfig.ClientId, xeroConfig.ClientSecret);
var response = await httpClient.SendAsync(requestMessage);
return "Success"; // This will change when I actually receive a 200 and the access token
}
catch (Exception ex)
{
logger.LogError(ex.Message);
return ex.Message;
}
}
Thanks in advance
Jon