using IM_API.Interface.Services; using Microsoft.AspNetCore.Connections; using Newtonsoft.Json; using StackExchange.Redis; using System.Numerics; using System.Security.Cryptography; using System.Text.Json; namespace IM_API.Services { public class RedisRefreshTokenService : IRefreshTokenService { private readonly ILogger _logger; //redis数据库 private readonly IDatabase _db; private IConfiguration configuration; //过期时长 private readonly TimeSpan _refreshTTL; public RedisRefreshTokenService(ILogger logger, IConnectionMultiplexer multiplexer, IConfiguration configuration) { _logger = logger; _db = multiplexer.GetDatabase(); this.configuration = configuration; //设置refresh过期时间 var days = int.Parse(this.configuration["Jwt:RefreshTokenDays"] ?? "30"); _refreshTTL = TimeSpan.FromDays(days); } private static string GenerateTokenStr() { var bytes = RandomNumberGenerator.GetBytes(32); return Convert.ToBase64String(bytes); } public async Task CreateRefreshTokenAsync(int userId, CancellationToken ct = default) { string token = GenerateTokenStr(); var payload = new { UserId = userId,CreateAt = DateTime.Now}; string json = JsonConvert.SerializeObject(payload); //token写入redis await _db.StringSetAsync(token,json,_refreshTTL); return token; } public async Task RevokeRefreshTokenAsync(string token, CancellationToken ct = default) { await _db.KeyDeleteAsync(token); } public async Task<(bool ok, int userId)> ValidateRefreshTokenAsync(string token, CancellationToken ct = default) { var json = await _db.StringGetAsync(token); if (json.IsNullOrEmpty) return (false,-1); try { var doc = JsonConvert.DeserializeObject(json); var userId = doc.GetProperty("UserId").GetInt32(); return (true,userId); } catch { return (false,-1); } } } }