JWT tokens til når du logger ind og passwword bliver hashet nu
This commit is contained in:
parent
5201e6e474
commit
05f09e57ff
@ -10,6 +10,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.14" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
|
@ -15,7 +15,7 @@ namespace Api.Controllers
|
||||
_context = context;
|
||||
}
|
||||
|
||||
|
||||
// For at få json webtokens til at virke skriv [Authorize] over de endpoints
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> GetDevices(int userId)
|
||||
{
|
||||
|
@ -1,6 +1,10 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Api.Models;
|
||||
using Api.DBAccess;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
|
||||
namespace Api.Controllers
|
||||
{
|
||||
@ -9,10 +13,12 @@ namespace Api.Controllers
|
||||
public class UserController : Controller
|
||||
{
|
||||
private readonly DBContext _context;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
public UserController(DBContext context)
|
||||
public UserController(DBContext context, IConfiguration configuration)
|
||||
{
|
||||
_context = context;
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
[HttpPost("Login")]
|
||||
@ -20,8 +26,9 @@ namespace Api.Controllers
|
||||
{
|
||||
DbAccess dBAccess = new DbAccess(_context);
|
||||
user = await dBAccess.Login(user);
|
||||
if (user.Id == 0) { return BadRequest(new { error = "User can't be logged in" }); }
|
||||
return Ok(user);
|
||||
if (user.Id == 0) { return Unauthorized(new { error = "Invalid username or password" }); }
|
||||
var token = GenerateJwtToken(user);
|
||||
return Ok(new { token, user.UserName, user.Id });
|
||||
}
|
||||
|
||||
[HttpPost("Create")]
|
||||
@ -41,5 +48,37 @@ namespace Api.Controllers
|
||||
if (!success) { return BadRequest(new { error = "User can't be edited" }); }
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpDelete("Delete/{userId}")]
|
||||
public async Task<IActionResult> DeleteUser(int userId)
|
||||
{
|
||||
DbAccess dbAccess = new DbAccess(_context);
|
||||
bool success = await dbAccess.DeleteUser(userId);
|
||||
if (!success) { return BadRequest(new { error = "User can't be deleted" }); }
|
||||
return Ok();
|
||||
}
|
||||
|
||||
private string GenerateJwtToken(User user)
|
||||
{
|
||||
var claims = new[]
|
||||
{
|
||||
new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString()),
|
||||
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
|
||||
new Claim(ClaimTypes.Name, user.UserName)
|
||||
};
|
||||
|
||||
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes
|
||||
(_configuration["JwtSettings:Key"]));
|
||||
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
|
||||
|
||||
var token = new JwtSecurityToken(
|
||||
_configuration["JwtSettings:Issuer"],
|
||||
_configuration["JwtSettings:Audience"],
|
||||
claims,
|
||||
expires: DateTime.Now.AddMinutes(30),
|
||||
signingCredentials: creds);
|
||||
|
||||
return new JwtSecurityTokenHandler().WriteToken(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Api.Models;
|
||||
using System.Text;
|
||||
using System.Runtime.Intrinsics.Arm;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
|
||||
namespace Api.DBAccess
|
||||
@ -28,6 +31,11 @@ namespace Api.DBAccess
|
||||
{
|
||||
user.Devices = new List<Device>();
|
||||
}
|
||||
string salt = Guid.NewGuid().ToString();
|
||||
string hashedPassword = ComputeHash(user.Password, SHA256.Create(), salt);
|
||||
|
||||
user.Salt = salt;
|
||||
user.Password = hashedPassword;
|
||||
|
||||
_context.Users.Add(user);
|
||||
return await _context.SaveChangesAsync() == 1;
|
||||
@ -36,10 +44,11 @@ namespace Api.DBAccess
|
||||
public async Task<User> Login(User user)
|
||||
{
|
||||
var profile = await _context.Users.FirstAsync(u => u.UserName == user.UserName);
|
||||
|
||||
string hashedPassword = ComputeHash(user.Password, SHA256.Create(), profile.Salt);
|
||||
|
||||
if (profile.Password == user.Password)
|
||||
if (hashedPassword == user.Password)
|
||||
{
|
||||
profile.Password = "";
|
||||
return profile;
|
||||
}
|
||||
return new User();
|
||||
@ -58,6 +67,25 @@ namespace Api.DBAccess
|
||||
return await _context.SaveChangesAsync() == 1;
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteUser(int userId)
|
||||
{
|
||||
var user = await _context.Users.Include(u => u.Devices).FirstOrDefaultAsync(u => u.Id == userId);
|
||||
if (user != null)
|
||||
{
|
||||
if (user.Devices != null && user.Devices.Count > 0)
|
||||
{
|
||||
foreach (var item in user.Devices)
|
||||
{
|
||||
var device = await _context.Devices.Include(d => d.Logs).FirstOrDefaultAsync(d => d.Id == item.Id);
|
||||
if (device != null) { _context.Devices.Remove(device); }
|
||||
}
|
||||
}
|
||||
_context.Users.Remove(user);
|
||||
return await _context.SaveChangesAsync() == 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task<List<Device>> ReadDevices(int userId)
|
||||
{
|
||||
var user = await _context.Users.Include(u => u.Devices).FirstOrDefaultAsync(u => u.Id == userId);
|
||||
@ -82,17 +110,6 @@ namespace Api.DBAccess
|
||||
return await _context.SaveChangesAsync() == 1;
|
||||
}
|
||||
|
||||
public async Task<List<TemperatureLogs>> ReadLogs(int deviceId)
|
||||
{
|
||||
var device = await _context.Devices.Include(d => d.Logs).FirstOrDefaultAsync(d => d.Id == deviceId);
|
||||
|
||||
if (device == null || device.Logs == null) { return new List<TemperatureLogs>(); }
|
||||
|
||||
var logs = device.Logs;
|
||||
|
||||
return logs;
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateDevice(Device device, int deviceId)
|
||||
{
|
||||
var device1 = await _context.Devices.FirstAsync(u => u.Id == deviceId);
|
||||
@ -105,5 +122,31 @@ namespace Api.DBAccess
|
||||
|
||||
return await _context.SaveChangesAsync() == 1;
|
||||
}
|
||||
|
||||
public async Task<List<TemperatureLogs>> ReadLogs(int deviceId)
|
||||
{
|
||||
var device = await _context.Devices.Include(d => d.Logs).FirstOrDefaultAsync(d => d.Id == deviceId);
|
||||
|
||||
if (device == null || device.Logs == null) { return new List<TemperatureLogs>(); }
|
||||
|
||||
var logs = device.Logs;
|
||||
|
||||
return logs;
|
||||
}
|
||||
|
||||
private static string ComputeHash(string input, HashAlgorithm algorithm, string salt)
|
||||
{
|
||||
Byte[] inputBytes = Encoding.UTF8.GetBytes(input);
|
||||
Byte[] saltBytes = Encoding.UTF8.GetBytes(salt);
|
||||
|
||||
// Combine salt and input bytes
|
||||
Byte[] saltedInput = new Byte[saltBytes.Length + inputBytes.Length];
|
||||
saltBytes.CopyTo(saltedInput, 0);
|
||||
inputBytes.CopyTo(saltedInput, saltBytes.Length);
|
||||
|
||||
Byte[] hashedBytes = algorithm.ComputeHash(saltedInput);
|
||||
|
||||
return BitConverter.ToString(hashedBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
public string Email { get; set; }
|
||||
|
||||
public string Salt { get; set; }
|
||||
|
||||
public List<Device>? Devices { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using System.Text;
|
||||
|
||||
namespace Api
|
||||
{
|
||||
@ -22,6 +25,29 @@ namespace Api
|
||||
|
||||
services.AddControllers();
|
||||
|
||||
services.AddAuthentication(x =>
|
||||
{
|
||||
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
}).AddJwtBearer(x =>
|
||||
{
|
||||
x.TokenValidationParameters = new TokenValidationParameters
|
||||
{
|
||||
ValidIssuer = _configuration["JwtSettings:Issuer"],
|
||||
ValidAudience = _configuration["JwtSettings:Audience"],
|
||||
IssuerSigningKey = new SymmetricSecurityKey
|
||||
(
|
||||
Encoding.UTF8.GetBytes(_configuration["JwtSettings:Key"])
|
||||
),
|
||||
ValidateIssuer = true,
|
||||
ValidateAudience = true,
|
||||
ValidateLifetime = true,
|
||||
ValidateIssuerSigningKey = true
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
services.AddCors(options =>
|
||||
{
|
||||
options.AddPolicy("AllowAll", builder =>
|
||||
|
Loading…
Reference in New Issue
Block a user