73 lines
2.3 KiB
C#
73 lines
2.3 KiB
C#
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
|
|
namespace API.Services;
|
|
|
|
public class TokenService : ITokenService
|
|
{
|
|
private readonly byte[] _secretKey;
|
|
|
|
public TokenService(IConfiguration? configuration = null)
|
|
{
|
|
var secret = configuration?["Jwt:Secret"] ?? "ChronoCCG_Super_Secret_Key_For_Jwt_Authentication_2026_Long_Key!";
|
|
_secretKey = Encoding.UTF8.GetBytes(secret);
|
|
}
|
|
|
|
public string GenerateToken(string username)
|
|
{
|
|
var payload = new TokenPayload
|
|
{
|
|
Username = username,
|
|
ExpiresAt = DateTimeOffset.UtcNow.AddDays(7).ToUnixTimeSeconds()
|
|
};
|
|
var json = JsonSerializer.Serialize(payload);
|
|
var payloadBytes = Encoding.UTF8.GetBytes(json);
|
|
var payloadBase64 = Convert.ToBase64String(payloadBytes);
|
|
|
|
using var hmac = new HMACSHA256(_secretKey);
|
|
var sigBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(payloadBase64));
|
|
var sigBase64 = Convert.ToBase64String(sigBytes);
|
|
|
|
return $"{payloadBase64}.{sigBase64}";
|
|
}
|
|
|
|
public string? ValidateToken(string? token)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(token)) return null;
|
|
|
|
var parts = token.Split('.');
|
|
if (parts.Length != 2) return null;
|
|
|
|
var payloadBase64 = parts[0];
|
|
var sigBase64 = parts[1];
|
|
|
|
using var hmac = new HMACSHA256(_secretKey);
|
|
var expectedSigBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(payloadBase64));
|
|
var expectedSigBase64 = Convert.ToBase64String(expectedSigBytes);
|
|
|
|
if (sigBase64 != expectedSigBase64) return null;
|
|
|
|
try
|
|
{
|
|
var payloadBytes = Convert.FromBase64String(payloadBase64);
|
|
var json = Encoding.UTF8.GetString(payloadBytes);
|
|
var payload = JsonSerializer.Deserialize<TokenPayload>(json);
|
|
if (payload == null || string.IsNullOrWhiteSpace(payload.Username)) return null;
|
|
|
|
if (DateTimeOffset.UtcNow.ToUnixTimeSeconds() > payload.ExpiresAt) return null;
|
|
|
|
return payload.Username;
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private class TokenPayload
|
|
{
|
|
public string Username { get; set; } = string.Empty;
|
|
public long ExpiresAt { get; set; }
|
|
}
|
|
} |