i'm trying to build an app with .net and react and now i'm working on authenticate react with .net by external login with github but i'm getting a weird 401 response always. i have this function in my controller:
[HttpPost("github/login")]
public async Task<IActionResult> LoginWithGithub([FromBody] ExternalLoginDto dto)
{
var AccessToken = await _githubHelper.GetAccessTokenAsync(dto.Code);
var userData = await _githubHelper.GetUserAsync(AccessToken!);
return Ok(userData);
}
it take the code after log in from a react app
this is the helper code, in the helper i get a token but the response from the /user endpoint is 401:
public class GithubHelper
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly IConfiguration _configuration;
private readonly IHttpContextAccessor _contextAccessor;
public GithubHelper(IHttpClientFactory httpClientFactory, IConfiguration configuration, IHttpContextAccessor contextAccessor)
{
_httpClientFactory = httpClientFactory;
_configuration = configuration;
_contextAccessor = contextAccessor;
}
public async Task<GitHubUser?> GetUserAsync(string token)
{
string userAgent = _contextAccessor?.HttpContext?.Request.Headers["User-Agent"]!;
using var httpClient = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://api.github.com/user");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
request.Headers.Add("User-Agent", userAgent);
HttpResponseMessage response = await httpClient.SendAsync(request);
var content = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
var userInfo = JsonConvert.DeserializeObject<GitHubUser>(content);
return userInfo;
}
else
{
throw new HttpRequestException($"GitHub API request failed with status code {response.StatusCode} and message {content}");
}
}
public async Task<string?> GetAccessTokenAsync(string code)
{
var request = new HttpRequestMessage(HttpMethod.Post, "https://github.com/login/oauth/access_token")
{
Content = new FormUrlEncodedContent(new Dictionary<string, string>
{
{"client_id", _configuration["Github:ClientId"]!},
{"client_secret", _configuration["Github:ClientSecret"]!},
{"code", code}
})
};
request.Headers.Add("Accept", "application/json");
var client = _httpClientFactory.CreateClient();
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
var jsonContent = await response.Content.ReadAsStringAsync();
var tokenResponse = JsonConvert.DeserializeObject<GitHubTokenResponse>(jsonContent);
return tokenResponse?.access_token;
}
return null;
}
}
}
catch the error or the reason why i'm getting a 401 response, even if the scopes are correct and the data are also correct and even sometime it works from postman, it's an oauth app what can be the reasons for that?
i solve it by sending the same user-agent for all requests.