Skip to content

Instantly share code, notes, and snippets.

@abdusco
Last active June 19, 2021 12:55
Show Gist options
  • Save abdusco/3979dfe8d00808a2deea13feb13aa0b6 to your computer and use it in GitHub Desktop.
Save abdusco/3979dfe8d00808a2deea13feb13aa0b6 to your computer and use it in GitHub Desktop.
JWT Cache
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory;
namespace JwtUtils
{
public interface IJwtCache
{
void Set(string key, JwtSecurityToken token);
Task<string> GetOrCreateAsync(string key, Func<Task<JwtSecurityToken>> tokenFactory = null);
}
public class JwtCacheOptions
{
public TimeSpan ClockSkew { get; set; } = TimeSpan.FromSeconds(15);
}
internal class JwtCache : IJwtCache
{
private readonly IMemoryCache _cache;
private readonly JwtCacheOptions _options;
public JwtCache(IMemoryCache cache, JwtCacheOptions options = null)
{
_cache = cache;
_options = options ?? new JwtCacheOptions();
}
public void Set(string key, JwtSecurityToken token)
{
if (token.ValidTo < DateTime.UtcNow)
{
throw new ArgumentException("Token has expired", nameof(token));
}
_cache.Set(key, token, token.ValidTo - _options.ClockSkew);
}
public Task<string> GetOrCreateAsync(string key, Func<Task<JwtSecurityToken>> tokenFactory = null)
{
if (tokenFactory == null)
{
return Task.FromResult(_cache.Get<string>(key));
}
return _cache.GetOrCreateAsync<string>(
key,
async entry =>
{
var token = await tokenFactory();
entry.AbsoluteExpiration = token.ValidTo - _options.ClockSkew;
return new JwtSecurityTokenHandler().WriteToken(token);
}
);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment