feat: User-Management mit Token-basierter Authentifizierung
Backend: - UserRecord Model + Users-Tabelle in DB - AuthService: SHA256-Passwort-Hashing, Token-Verwaltung (ConcurrentDictionary) - AuthMiddleware: Schützt alle /api/-Routes (außer /api/auth/login) - AuthEndpoint: Login, Logout, Me - Default-User admin/admin wird automatisch erstellt Frontend: - Login-Page mit Formular (Enter-Key-Support) - Globaler Fetch-Interceptor: 401 → automatisch Login-Redirect - Auth-Check beim App-Start und bei Hash-Änderungen - Logout-Link im Dashboard-Header - Login-CSS: Zentrierte Login-Box
This commit is contained in:
1 parent
a1c54bf376
commit
9a59ae686d
13 files changed
+446
-3
No files matched your search
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace Gott.Services;
|
||||
|
||||
public class AuthService
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, string> _tokens = new(); // token -> userId
|
||||
|
||||
public string HashPassword(string password)
|
||||
{
|
||||
var bytes = SHA256.HashData(Encoding.UTF8.GetBytes(password));
|
||||
return Convert.ToHexStringLower(bytes);
|
||||
}
|
||||
|
||||
public bool VerifyPassword(string password, string hash)
|
||||
{
|
||||
return HashPassword(password) == hash;
|
||||
}
|
||||
|
||||
public string CreateToken(string userId)
|
||||
{
|
||||
var token = Convert.ToHexStringLower(RandomNumberGenerator.GetBytes(32));
|
||||
_tokens[token] = userId;
|
||||
return token;
|
||||
}
|
||||
|
||||
public string ValidateToken(string token)
|
||||
{
|
||||
if (string.IsNullOrEmpty(token)) return null;
|
||||
return _tokens.TryGetValue(token, out var userId) ? userId : null;
|
||||
}
|
||||
|
||||
public void RevokeToken(string token)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(token))
|
||||
_tokens.TryRemove(token, out _);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user