29 lines
840 B
C#
29 lines
840 B
C#
using StackExchange.Redis;
|
|
|
|
namespace OED.Api.Infrastructure.Auth;
|
|
|
|
public interface IStateStore
|
|
{
|
|
Task<string> GenerateAsync();
|
|
Task<bool> ValidateAndConsumeAsync(string state);
|
|
}
|
|
|
|
public class StateStore(IConnectionMultiplexer redis) : IStateStore
|
|
{
|
|
private readonly IDatabase _db = redis.GetDatabase();
|
|
private static readonly TimeSpan StateTtl = TimeSpan.FromMinutes(10);
|
|
|
|
public async Task<string> GenerateAsync()
|
|
{
|
|
var state = Guid.NewGuid().ToString("N");
|
|
await _db.StringSetAsync($"oauth:state:{state}", "1", StateTtl);
|
|
return state;
|
|
}
|
|
|
|
public async Task<bool> ValidateAndConsumeAsync(string state)
|
|
{
|
|
// Delete returns true only if the key existed — atomic check + delete in one operation
|
|
return await _db.KeyDeleteAsync($"oauth:state:{state}");
|
|
}
|
|
}
|