I’m getting a 401 unauthorized error when trying to call my .NET Core Web API endpoint with a bearer token using jQuery AJAX.
Here’s my frontend JavaScript code:
$(function() {
$("#loginBtn").on('click', function(event) {
event.preventDefault();
var credentials = JSON.stringify({
Email: $("#userEmail").val(),
Pass: $("#userPass").val()
});
$.ajax({
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
method: "POST",
url: "https://localhost:5001/api/Auth/signin",
data: credentials,
dataType: "json",
success: function(response) {
if (response && response.token) {
console.log('Login successful');
fetchUserData(response.token);
} else {
console.log('Authentication failed');
}
},
error: function(xhr, status, err) {
alert('Login error: ' + err);
}
});
});
function fetchUserData(authToken) {
$.ajax({
url: 'https://localhost:5001/api/Users',
type: 'GET',
headers: {
'Authorization': 'Bearer ' + authToken
},
contentType: "application/json",
dataType: 'json',
success: function(data) {
console.log('User data:', data);
},
error: function(xhr) {
console.log('Error fetching users:', xhr.status);
}
});
}
});
My backend controller looks like this:
[HttpPost]
[Route("signin")]
public async Task<IActionResult> SignIn([FromBody] LoginRequest request)
{
var appUser = await _userManager.FindByEmailAsync(request.Email);
if (appUser != null && await _userManager.CheckPasswordAsync(appUser, request.Pass))
{
var roles = await _userManager.GetRolesAsync(appUser);
var claims = new List<Claim>
{
new Claim(ClaimTypes.Email, appUser.Email),
new Claim(JwtRegisteredClaimNames.Sub, appUser.Id),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};
foreach (var role in roles)
{
claims.Add(new Claim(ClaimTypes.Role, role));
}
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["JwtSettings:Key"]));
var jwt = new JwtSecurityToken(
issuer: _config["JwtSettings:Issuer"],
audience: _config["JwtSettings:Audience"],
expires: DateTime.UtcNow.AddHours(2),
claims: claims,
signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256)
);
return Ok(new {
token = new JwtSecurityTokenHandler().WriteToken(jwt),
expires = jwt.ValidTo
});
}
return BadRequest();
}
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class UsersController : ControllerBase
{
private readonly DataContext _db;
public UsersController(DataContext db)
{
_db = db;
}
[HttpGet]
public async Task<ActionResult<List<User>>> GetAllUsers()
{
return await _db.Users.ToListAsync();
}
}
The login endpoint works fine and returns a valid JWT token. However, when I try to use that token to access the protected Users endpoint, I keep getting a 401 error. Without the [Authorize] attribute, the API call works perfectly. What am I doing wrong with the token authentication?