/
koskv
/
TeamSync-Bot
Обзор
Документация
Войти
/
koskv
/
TeamSync-Bot
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/main/java/org/example/teamsyncbot/client/auth/AuthService.java
86 строк
3 KB
Koskv
Add: Get All Users
13 дек 2025, 23:43
13 дек 2025, 23:43
6966893
Код
Авторство
О чём код?
package org.example.teamsyncbot.client.auth; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.nio.charset.StandardCharsets; import java.time.Duration; import java.time.Instant; import java.util.Base64; @Service @Slf4j public class AuthService { private final TeamSyncAuthClient authClient; private final ObjectMapper objectMapper; private volatile String cachedToken = null; private volatile Instant tokenExpiry = null; private static final Duration REFRESH_BEFORE = Duration.ofMinutes(2); public AuthService(TeamSyncAuthClient authClient, ObjectMapper objectMapper) { this.authClient = authClient; this.objectMapper = objectMapper; } /** * Возвращает актуальный токен (из кеша или после обновления). * Потокобезопасен (synchronized). */ public synchronized String getValidToken() { Instant now = Instant.now(); if (cachedToken != null && tokenExpiry != null && now.isBefore(tokenExpiry.minus(REFRESH_BEFORE))) { log.trace("Используем кешированный токен (истекает в {})", tokenExpiry); return cachedToken; } log.info("Получение нового токена..."); String fullToken = authClient.loginAndGetToken(); String jwt = fullToken.substring(7); // убираем "Bearer " Instant expiry = extractExpiry(jwt); this.cachedToken = fullToken; this.tokenExpiry = expiry; log.info("✅ Токен обновлён. Истекает: {}", expiry); return fullToken; } /** * Сбрасывает кешированный токен — например, при 401 Unauthorized. */ public synchronized void invalidateToken() { this.cachedToken = null; this.tokenExpiry = null; log.info("Токен сброшен"); } private Instant extractExpiry(String jwt) { try { String[] parts = jwt.split("\\."); if (parts.length < 2) { throw new IllegalArgumentException("JWT должен содержать header и payload"); } String payload = new String( Base64.getUrlDecoder().decode(parts[1]), StandardCharsets.UTF_8 ); JsonNode node = objectMapper.readTree(payload); long exp = node.get("exp").asLong(); // seconds return Instant.ofEpochSecond(exp); } catch (Exception e) { log.warn("Не удалось извлечь 'exp' из JWT. Используем 1 час по умолчанию.", e); return Instant.now().plus(Duration.ofHours(1)); } } }