/
softailor
/
gridient
Обзор
Документация
Войти
/
softailor
/
gridient
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
backend/Gridient.Infrastructure.Authentication.Local/Features/Auth/Commands/RefreshTokenCommandHandler.cs
111 строк
5 KB
Jenkins
Auto add
18 фев 2026, 10:19
18 фев 2026, 10:19
1e6c4f8
Код
Авторство
О чём код?
using Gridient.Core.Services.Interfaces; using Gridient.Infrastructure.Authentication.Local.Models; using Gridient.Infrastructure.Authentication.Local.Options; using Gridient.Infrastructure.Authentication.Local.Repositories; using Gridient.Infrastructure.Authentication.Local.Services; using MediatR; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System.Security.Claims; using UserModel = Gridient.Core.Models.User; namespace Gridient.Infrastructure.Authentication.Local.Features.Auth.Commands { /// <summary> /// Обработчик команды для обновления токена доступа /// </summary> public class RefreshTokenCommandHandler : IRequestHandler<RefreshTokenCommand, AuthResponseModel?> { private readonly IRefreshTokenRepository _refreshTokenRepository; private readonly IUserService _userService; private readonly ITokenService _tokenService; private readonly IAuthUserRepository _authUserRepository; private readonly JwtOptions _jwtOptions; private readonly ILogger<RefreshTokenCommandHandler> _logger; public RefreshTokenCommandHandler( IRefreshTokenRepository refreshTokenRepository, IUserService userService, ITokenService tokenService, IAuthUserRepository authUserRepository, IOptions<JwtOptions> jwtOptions, ILogger<RefreshTokenCommandHandler> logger) { _refreshTokenRepository = refreshTokenRepository; _userService = userService; _tokenService = tokenService; _authUserRepository = authUserRepository; _jwtOptions = jwtOptions.Value; _logger = logger; } public async Task<AuthResponseModel?> Handle(RefreshTokenCommand request, CancellationToken cancellationToken) { _logger.LogDebug("Начало обновления токена"); var authUser = await _refreshTokenRepository.GetUserByRefreshTokenAsync(request.RefreshToken, cancellationToken); if (authUser == null) { _logger.LogWarning("Пользователь не найден для refresh token"); return null; } // Проверяем срок действия токена var tokenEntity = await _refreshTokenRepository.GetByTokenAsync(request.RefreshToken, cancellationToken); if (tokenEntity == null || tokenEntity.ExpiresAt < DateTime.UtcNow) { _logger.LogWarning("Refresh token истек или не найден"); return null; } // Получаем пользователя Core для получения групп var coreUser = await _userService.GetByLoginAsync(authUser.Login, cancellationToken); if (coreUser == null) { _logger.LogWarning("Core пользователь не найден для логина: {Login}", authUser.Login); return null; } var result = await GenerateTokensAsync(coreUser, cancellationToken); _logger.LogInformation("Токен успешно обновлен для пользователя: {Login}", authUser.Login); return result; } private async Task<AuthResponseModel> GenerateTokensAsync(UserModel coreUser, CancellationToken cancellationToken) { var accessTokenExpires = DateTime.UtcNow.AddMinutes(_jwtOptions.AccessTokenLifetimeMinutes); var refreshTokenExpires = DateTime.UtcNow.AddHours(_jwtOptions.RefreshTokenLifetimeHours); // Базовые claims var baseClaims = new List<Claim> { new(ClaimTypes.NameIdentifier, coreUser.Id.ToString()), new(ClaimTypes.Name, coreUser.Login), }; // Генерируем refresh token (без ролей) var refreshToken = _tokenService.GenerateRefreshToken(baseClaims, refreshTokenExpires); // Используем базовые claims для access token (без ролей) var accessClaims = new List<Claim>(baseClaims); var accessToken = _tokenService.GenerateAccessToken(accessClaims, accessTokenExpires); // Сохраняем refresh token await _refreshTokenRepository.SaveTokenAsync( coreUser.Login, refreshToken, DateTime.UtcNow, refreshTokenExpires, cancellationToken); return new AuthResponseModel { AccessToken = accessToken, AccessTokenExp = accessTokenExpires, RefreshToken = refreshToken }; } } }