10 12 25
Вроде всё доделал. Авторификацию. (осталось закрытие сессии и получение списка активных сессии)
This commit is contained in:
parent
00fc9e3926
commit
7072882b0b
@ -14,6 +14,10 @@ public final class ClientInfoService {
|
|||||||
|
|
||||||
private ClientInfoService() { }
|
private ClientInfoService() { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Собирает строку с информацией о клиенте:
|
||||||
|
* User-Agent, client-hints и удалённый IP.
|
||||||
|
*/
|
||||||
public static String buildClientInfoString(Session wsSession) {
|
public static String buildClientInfoString(Session wsSession) {
|
||||||
if (wsSession == null) {
|
if (wsSession == null) {
|
||||||
return CLIENT_INFO_UNKNOWN;
|
return CLIENT_INFO_UNKNOWN;
|
||||||
@ -29,14 +33,8 @@ public final class ClientInfoService {
|
|||||||
String secChPlatform = getFirstHeader(req, "Sec-CH-UA-Platform");
|
String secChPlatform = getFirstHeader(req, "Sec-CH-UA-Platform");
|
||||||
String secChMobile = getFirstHeader(req, "Sec-CH-UA-Mobile");
|
String secChMobile = getFirstHeader(req, "Sec-CH-UA-Mobile");
|
||||||
|
|
||||||
// --- Исправленный блок определения IP ---
|
// IP берём через общий метод, чтобы не дублировать логику
|
||||||
String remoteIp = "";
|
String remoteIp = extractClientIp(wsSession);
|
||||||
SocketAddress rawAddr = wsSession.getRemoteAddress();
|
|
||||||
if (rawAddr instanceof InetSocketAddress inet) {
|
|
||||||
if (inet.getAddress() != null) {
|
|
||||||
remoteIp = inet.getAddress().getHostAddress();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
@ -55,7 +53,7 @@ public final class ClientInfoService {
|
|||||||
appendSep(sb);
|
appendSep(sb);
|
||||||
sb.append("mobile=").append(secChMobile);
|
sb.append("mobile=").append(secChMobile);
|
||||||
}
|
}
|
||||||
if (!remoteIp.isEmpty()) {
|
if (remoteIp != null && !remoteIp.isEmpty()) {
|
||||||
appendSep(sb);
|
appendSep(sb);
|
||||||
sb.append("remote=").append(remoteIp);
|
sb.append("remote=").append(remoteIp);
|
||||||
}
|
}
|
||||||
@ -64,6 +62,49 @@ public final class ClientInfoService {
|
|||||||
return result.isEmpty() ? CLIENT_INFO_UNKNOWN : result;
|
return result.isEmpty() ? CLIENT_INFO_UNKNOWN : result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Пытается вытащить реальный IP клиента из WebSocket-сессии.
|
||||||
|
*
|
||||||
|
* Приоритет:
|
||||||
|
* 1) X-Forwarded-For (если стоим за прокси / балансировщиком)
|
||||||
|
* 2) X-Real-IP
|
||||||
|
* 3) remoteAddress из WebSocket-сессии
|
||||||
|
*/
|
||||||
|
public static String extractClientIp(Session wsSession) {
|
||||||
|
if (wsSession == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpgradeRequest req = wsSession.getUpgradeRequest();
|
||||||
|
|
||||||
|
// 1) X-Forwarded-For: может быть список IP через запятую
|
||||||
|
if (req != null) {
|
||||||
|
String xff = getFirstHeader(req, "X-Forwarded-For");
|
||||||
|
if (xff != null && !xff.isBlank()) {
|
||||||
|
String first = xff.split(",")[0].trim();
|
||||||
|
if (!first.isBlank()) {
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) X-Real-IP
|
||||||
|
String xRealIp = getFirstHeader(req, "X-Real-IP");
|
||||||
|
if (xRealIp != null && !xRealIp.isBlank()) {
|
||||||
|
return xRealIp.trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3) fallback: remoteAddress из WebSocket-сессии
|
||||||
|
SocketAddress rawAddr = wsSession.getRemoteAddress();
|
||||||
|
if (rawAddr instanceof InetSocketAddress inet) {
|
||||||
|
if (inet.getAddress() != null) {
|
||||||
|
return inet.getAddress().getHostAddress();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static String extractPreferredLanguageTag(Session wsSession) {
|
public static String extractPreferredLanguageTag(Session wsSession) {
|
||||||
if (wsSession == null) {
|
if (wsSession == null) {
|
||||||
return LANGUAGE_UNKNOWN;
|
return LANGUAGE_UNKNOWN;
|
||||||
@ -102,5 +143,6 @@ public final class ClientInfoService {
|
|||||||
if (sb.length() > 0) {
|
if (sb.length() > 0) {
|
||||||
sb.append("; ");
|
sb.append("; ");
|
||||||
}
|
}
|
||||||
|
// если строка пустая — разделитель не нужен
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -15,12 +15,11 @@ import shine.db.dao.ActiveSessionsDAO;
|
|||||||
import shine.db.entities.ActiveSession;
|
import shine.db.entities.ActiveSession;
|
||||||
import shine.db.entities.SolanaUser;
|
import shine.db.entities.SolanaUser;
|
||||||
import shine.geo.ClientInfoService;
|
import shine.geo.ClientInfoService;
|
||||||
|
import shine.geo.GeoLookupService;
|
||||||
import utils.crypto.Ed25519Util;
|
import utils.crypto.Ed25519Util;
|
||||||
|
|
||||||
import org.eclipse.jetty.websocket.api.Session;
|
import org.eclipse.jetty.websocket.api.Session;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.SocketAddress;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
@ -178,17 +177,26 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler {
|
|||||||
String clientInfoFromRequest = ClientInfoService.buildClientInfoString(wsSession);
|
String clientInfoFromRequest = ClientInfoService.buildClientInfoString(wsSession);
|
||||||
String userLanguage = ClientInfoService.extractPreferredLanguageTag(wsSession);
|
String userLanguage = ClientInfoService.extractPreferredLanguageTag(wsSession);
|
||||||
|
|
||||||
String clientIp = "";
|
String clientIp = null;
|
||||||
if (wsSession != null) {
|
if (wsSession != null) {
|
||||||
SocketAddress rawAddr = wsSession.getRemoteAddress();
|
// стандартный метод получения IP
|
||||||
if (rawAddr instanceof InetSocketAddress inet) {
|
clientIp = ClientInfoService.extractClientIp(wsSession);
|
||||||
if (inet.getAddress() != null) {
|
|
||||||
clientIp = inet.getAddress().getHostAddress();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// TODO и сдесь тоже переписываем получение ИП адреса на стандартный метод и тоже дёргаем запрос геолокации который никуда не сохраняем просто что бы он в кэш сервера попал
|
|
||||||
|
|
||||||
|
// Дёргаем запрос геолокации (ничего не сохраняем в сессию),
|
||||||
|
// нужно лишь для того, чтобы данные попали в кэш сервера.
|
||||||
|
if (clientIp != null && !clientIp.isBlank()) {
|
||||||
|
try {
|
||||||
|
GeoLookupService.resolveCountryCityOrIpWithCache(clientIp);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// геолокация не критична, можно тихо залогировать на debug
|
||||||
|
log.debug("Geo lookup failed for ip={}", clientIp, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clientIp == null) {
|
||||||
|
clientIp = "";
|
||||||
|
}
|
||||||
|
|
||||||
// --- создаём запись ActiveSession и сохраняем в БД ---
|
// --- создаём запись ActiveSession и сохраняем в БД ---
|
||||||
ActiveSessionsDAO dao = ActiveSessionsDAO.getInstance();
|
ActiveSessionsDAO dao = ActiveSessionsDAO.getInstance();
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import shine.db.dao.SolanaUsersDAO;
|
|||||||
import shine.db.entities.ActiveSession;
|
import shine.db.entities.ActiveSession;
|
||||||
import shine.db.entities.SolanaUser;
|
import shine.db.entities.SolanaUser;
|
||||||
import shine.geo.ClientInfoService;
|
import shine.geo.ClientInfoService;
|
||||||
|
import shine.geo.GeoLookupService;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
@ -125,8 +126,20 @@ public class Net_RefreshSession_Handler implements JsonMessageHandler {
|
|||||||
String userLanguage = null;
|
String userLanguage = null;
|
||||||
|
|
||||||
if (ctx != null && ctx.getWsSession() != null) {
|
if (ctx != null && ctx.getWsSession() != null) {
|
||||||
clientIp = "8.8.8.8"; //TODO сделать нормальное получение ип адреса
|
// Нормальное получение IP-адреса клиента
|
||||||
// и сделать запрос геолокации и никуда его не сохранять запрос нужен просто что бы в кэш данные добавилиь если нужно
|
clientIp = ClientInfoService.extractClientIp(ctx.getWsSession());
|
||||||
|
|
||||||
|
// Сделать запрос геолокации и никуда её не сохранять:
|
||||||
|
// вызов с кэшированием в БД, нужно только для прогрева кэша.
|
||||||
|
if (clientIp != null && !clientIp.isBlank()) {
|
||||||
|
try {
|
||||||
|
GeoLookupService.resolveCountryCityOrIpWithCache(clientIp);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Геолокация не критична, просто логируем на debug/trace при желании
|
||||||
|
log.debug("Geo lookup failed for ip={}", clientIp, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
clientInfoFromRequest = ClientInfoService.buildClientInfoString(ctx.getWsSession());
|
clientInfoFromRequest = ClientInfoService.buildClientInfoString(ctx.getWsSession());
|
||||||
userLanguage = ClientInfoService.extractPreferredLanguageTag(ctx.getWsSession());
|
userLanguage = ClientInfoService.extractPreferredLanguageTag(ctx.getWsSession());
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user