Токены, правильная работа
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
using Knot.Contracts.Auth.Application.Auth.DTOs;
|
||||
using Knot.Shared.Kernel;
|
||||
using MediatR;
|
||||
|
||||
namespace Knot.Modules.Auth.Application.Users.RefreshToken;
|
||||
|
||||
public record RefreshTokenCommand(string RefreshToken) : ICommand<AuthResponseDto>;
|
||||
@@ -0,0 +1,65 @@
|
||||
using Knot.Contracts.Auth.Application.Abstractions;
|
||||
using Knot.Contracts.Auth.Application.Auth.DTOs;
|
||||
using Knot.Contracts.Auth.Domain;
|
||||
using Knot.Shared.Kernel;
|
||||
using MediatR;
|
||||
|
||||
namespace Knot.Modules.Auth.Application.Users.RefreshToken;
|
||||
|
||||
internal sealed class RefreshTokenCommandHandler : ICommandHandler<RefreshTokenCommand, AuthResponseDto>
|
||||
{
|
||||
private readonly IUserRepository _userRepository;
|
||||
private readonly IJwtTokenProvider _tokenProvider;
|
||||
|
||||
public RefreshTokenCommandHandler(
|
||||
IUserRepository userRepository,
|
||||
IJwtTokenProvider tokenProvider)
|
||||
{
|
||||
_userRepository = userRepository;
|
||||
_tokenProvider = tokenProvider;
|
||||
}
|
||||
|
||||
public async Task<Result<AuthResponseDto>> Handle(RefreshTokenCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(request.RefreshToken))
|
||||
{
|
||||
return Result.Failure<AuthResponseDto>(
|
||||
new Error("Auth.InvalidRefreshToken", "Refresh token is required"));
|
||||
}
|
||||
|
||||
var user = await _userRepository.GetByRefreshTokenAsync(request.RefreshToken, cancellationToken);
|
||||
if (user == null)
|
||||
{
|
||||
return Result.Failure<AuthResponseDto>(
|
||||
new Error("Auth.InvalidRefreshToken", "Invalid or expired refresh token"));
|
||||
}
|
||||
|
||||
// Check if refresh token has expired
|
||||
if (user.RefreshTokenExpiry.HasValue && user.RefreshTokenExpiry.Value < DateTime.UtcNow)
|
||||
{
|
||||
// Clear expired refresh token
|
||||
user.SetRefreshToken(null, null);
|
||||
await _userRepository.UpdateAsync(user, cancellationToken);
|
||||
|
||||
return Result.Failure<AuthResponseDto>(
|
||||
new Error("Auth.RefreshTokenExpired", "Refresh token has expired. Please login again."));
|
||||
}
|
||||
|
||||
var newAccessToken = _tokenProvider.Generate(user.Id, user.Username, user.DisplayName, user.Avatar);
|
||||
|
||||
var newRefreshToken = _tokenProvider.GenerateRefreshToken();
|
||||
var newRefreshExpiry = _tokenProvider.GetRefreshTokenExpiry();
|
||||
user.SetRefreshToken(newRefreshToken, newRefreshExpiry);
|
||||
await _userRepository.UpdateAsync(user, cancellationToken);
|
||||
|
||||
return Result.Success(new AuthResponseDto
|
||||
{
|
||||
AccessToken = newAccessToken,
|
||||
RefreshToken = newRefreshToken,
|
||||
UserId = user.Id,
|
||||
Username = user.Username,
|
||||
DisplayName = user.DisplayName,
|
||||
Avatar = user.Avatar
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user