92 lines
3.1 KiB
C#
92 lines
3.1 KiB
C#
using Microsoft.Extensions.Configuration;
|
|
using Syski.Data;
|
|
using System;
|
|
using System.Linq;
|
|
using System.Security.Cryptography;
|
|
|
|
namespace Syski.API.Services
|
|
{
|
|
public class UserTokenManager
|
|
{
|
|
|
|
private readonly SyskiDBContext context;
|
|
private readonly IConfiguration configuration;
|
|
|
|
public UserTokenManager(SyskiDBContext context, IConfiguration configuration)
|
|
{
|
|
this.context = context;
|
|
this.configuration = configuration;
|
|
}
|
|
|
|
|
|
public AuthenticationToken CreateToken(ApplicationUser user, ref string refreshToken)
|
|
{
|
|
AuthenticationToken token = GenerateToken(user, ref refreshToken);
|
|
context.Add(token);
|
|
context.SaveChanges();
|
|
return token;
|
|
}
|
|
|
|
public AuthenticationToken CreateToken(ApplicationUser user, ref string refreshToken, string previousTokenId)
|
|
{
|
|
AuthenticationToken token = GenerateToken(user, ref refreshToken);
|
|
var previousToken = context.AuthenticationTokens.FirstOrDefault(t => t.Id == new Guid(previousTokenId));
|
|
context.Add(token);
|
|
context.SaveChanges();
|
|
if (previousToken != null)
|
|
{
|
|
previousToken.Active = false;
|
|
SetPreviousToken(ref token, ref previousToken);
|
|
context.SaveChanges();
|
|
}
|
|
return token;
|
|
}
|
|
|
|
public bool CheckValidRefreshToken(string refreshToken, string tokenId)
|
|
{
|
|
return context.AuthenticationTokens.Any(t => t.Id == new Guid(tokenId) && t.Active && t.RefreshToken == refreshToken);
|
|
}
|
|
|
|
private void SetPreviousToken(ref AuthenticationToken nextToken, ref AuthenticationToken previousToken)
|
|
{
|
|
previousToken.NextTokenId = nextToken.Id;
|
|
nextToken.PreviousTokenId = previousToken.Id;
|
|
}
|
|
|
|
private AuthenticationToken GenerateToken(ApplicationUser user, ref string refreshToken)
|
|
{
|
|
AuthenticationToken result = null;
|
|
if (refreshToken == null)
|
|
{
|
|
refreshToken = GenerateRefreshToken();
|
|
}
|
|
result = new AuthenticationToken()
|
|
{
|
|
Id = new Guid(),
|
|
User = user,
|
|
UserId = user.Id,
|
|
TokenType = "Bearer",
|
|
Issuer = configuration["Jwt:Issuer"],
|
|
Audience = configuration["Jwt:Audience"],
|
|
Subject = user.Email,
|
|
Expires = DateTime.Now.AddMinutes(Convert.ToDouble(configuration["Jwt:ExpireInMinutes"])),
|
|
NotBefore = DateTime.Now,
|
|
RefreshToken = refreshToken,
|
|
Active = true
|
|
};
|
|
return (result);
|
|
}
|
|
|
|
private string GenerateRefreshToken()
|
|
{
|
|
var randomNumber = new byte[128];
|
|
using (var rng = RandomNumberGenerator.Create())
|
|
{
|
|
rng.GetBytes(randomNumber);
|
|
return Convert.ToBase64String(randomNumber);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|