I'm trying to build login/register application and I'm using JSON Web Tokens. When user is logged in, it's creating a token and storing it in the database. But this token doesn't work. Thanks for help.
This is program.cs
:
builder.Services.Configure<AuthModel>(builder.Configuration.GetSection("JwtSettings"));
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(x =>
{
x.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = config["JwtSettings:Issuer"],
ValidAudience = config["JwtSettings:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config["JwtSettings:Key"])),
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
};
});
.
.
.
app.UseAuthentication();
app.UseRouting();
app.UseAuthorization();
This is my appsettings.json
file:
{
"JwtSettings": {
"Issuer": "localhost",
"Audience": "localhost",
"Key": "D9tXE03Lpi4oUWVpuu0p"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
This is the controller for login screen
[HttpPost]
public IActionResult Index(string inputEmail, string inputPassword)
{
if (um.Get(x => x.Email == inputEmail) == null)
{
return BadRequest("there is no e mail that you send");
}
if (!BCrypt.Net.BCrypt.Verify(inputPassword, um.Get(x => x.Email == inputEmail).PasswordHash))
{
return BadRequest("wrong pass");
}
//var claims = new[]
//{
// new Claim(JwtRegisteredClaimNames.Email, userName),
//};
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_authSettings.Value.Key));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
var jwtSecurityToken = new JwtSecurityToken(
issuer: _authSettings.Value.Issuer,
audience: _authSettings.Value.Audience,
claims: null,
expires: DateTime.Now.AddHours(1),
notBefore: DateTime.Now,
signingCredentials: credentials);
var token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
User user = um.Get(x => x.Email == inputEmail);
user.Token = token;
um.UserUpdate(user);
return RedirectToAction("Index", "User", token);
}
And this is my homepage:
[Authorize]
public class UserController : Controller
{
[HttpGet]
public IActionResult Index()
{
return View();
}
}
When the user logged in there is a token is creating and when I'm trying to get request with bearer token; in Postman, it returns 200, but web pages returns a http 401. Thanks for help.
return RedirectToAction("Index", "User", token);
Your token is in the route data, not in the request header. But we need to put it into the request header. You also can find the difference of the request header between Postman request and server request.
Add session to pass the token:
HttpContext.Session.SetString("JWToken", token);
return RedirectToAction("Index", "User");
In program.cs add:
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession();
...
app.UseSession();
app.Use(async (context, next) =>
{
var JWToken = context.Session.GetString("JWToken");
if (!string.IsNullOrEmpty(JWToken))
{
context.Request.Headers.Add("Authorization", "Bearer " + JWToken);
}
await next();
});
app.UseAuthentication();