Files
gott/Services/AuthService.cs
Meleki f203ed7f47 feat: Auth-Tokens in SQLite persistieren statt in-memory
Tokens überleben jetzt App-Restarts. AuthService schreibt/liest
Tokens aus einer 'tokens'-Tabelle in der SQLite-DB.
Logout (RevokeToken) funktioniert weiterhin korrekt.
2026-03-03 10:07:06 +01:00

75 lines
2.1 KiB
C#

using System;
using System.Security.Cryptography;
using System.Text;
using Dapper;
using Microsoft.Data.Sqlite;
namespace Gott.Services;
public class AuthService
{
private readonly string _connectionString;
public AuthService(string dbPath)
{
_connectionString = $"Data Source={dbPath}";
InitializeTable();
}
private SqliteConnection CreateConnection()
{
var conn = new SqliteConnection(_connectionString);
conn.Open();
return conn;
}
private void InitializeTable()
{
using var conn = CreateConnection();
conn.Execute(@"
CREATE TABLE IF NOT EXISTS tokens (
token TEXT NOT NULL PRIMARY KEY,
user_id TEXT NOT NULL,
created_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_tokens_user ON tokens(user_id);
");
}
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));
using var conn = CreateConnection();
conn.Execute(
"INSERT INTO tokens (token, user_id, created_at) VALUES (@token, @userId, @now)",
new { token, userId, now = DateTime.UtcNow.ToString("o") });
return token;
}
public string ValidateToken(string token)
{
if (string.IsNullOrEmpty(token)) return null;
using var conn = CreateConnection();
return conn.QuerySingleOrDefault<string>(
"SELECT user_id FROM tokens WHERE token = @token", new { token });
}
public void RevokeToken(string token)
{
if (string.IsNullOrEmpty(token)) return;
using var conn = CreateConnection();
conn.Execute("DELETE FROM tokens WHERE token = @token", new { token });
}
}