- Wiersz odpowiada jednej sesji usługi sieciowej — z własnym identyfikatorem i terminem wygaśnięcia.
- Indeks unikalny na kolumnie
SESSIONIDwyklucza wydanie dwóch sesji o tym samym identyfikatorze. - Kolumna
TERMINogranicza czas życia sesji, co jest podstawowym zabezpieczeniem przy dostępie programowym. - Wygasłe wiersze trzeba usuwać cyklicznie — inaczej tabela rośnie bez ograniczeń.
Do czego służy tabela [dbo].[_users_ws]
Gdy z systemem łączy się nie człowiek, lecz inny program — sklep internetowy pobierający stany, aplikacja mobilna, system kontrahenta — uwierzytelnianie hasłem przy każdym żądaniu byłoby zarówno powolne, jak i niebezpieczne. Zamiast tego program loguje się raz i otrzymuje tymczasowy identyfikator sesji. Tabela [dbo].[_users_ws] przechowuje te identyfikatory.
Mechanizm jest prosty i sprawdzony. Po poprawnym uwierzytelnieniu powstaje wiersz zawierający login, wygenerowany identyfikator sesji oraz termin jej ważności. Każde kolejne żądanie posługuje się już samym identyfikatorem, a system sprawdza dwie rzeczy: czy taki wiersz istnieje i czy termin jeszcze nie minął.
Ograniczenie czasu życia sesji jest tu zabezpieczeniem podstawowym. Przechwycony identyfikator pozwala działać w imieniu użytkownika, ale tylko do momentu wygaśnięcia — a ten powinien być liczony w minutach, nie w dniach. Status w kolumnie ACH pozwala dodatkowo unieważnić sesję natychmiast, bez czekania na upływ terminu.
Krótki termin ważności ogranicza skutki przechwycenia identyfikatora — po jego upływie jest bezwartościowy.
Budowa tabeli — wykaz kolumn
Sześć kolumn wystarcza do obsługi sesji: identyfikacja, właściciel, termin i status.
| Kolumna | Typ | Wymagana | Znaczenie |
|---|---|---|---|
ACH | varchar(1) tekst do 1 znaków | tak | Status reklordu, wartość domyślna 1, rekrod usunięty wartość X |
ID_USERS_WS | int liczba całkowita | tak | Identyfiaktor wiersza tabeli |
KIEDY | datetime data i godzina | tak | Data i czas utworzenia zapisu |
LOGIN | varchar(50) tekst do 50 znaków | tak | Login użytkownika WebService |
SESSIONID | varchar(50) tekst do 50 znaków | tak | Tymczasowy unikalny identyfikator sesji |
TERMIN | datetime data i godzina | tak | Termin ważności sesji zezwalajacy na zalogowanie |
Kolumna SESSIONID ma pięćdziesiąt znaków, co pozwala zapisać identyfikator o wystarczającej entropii. Wartość powinna pochodzić z generatora losowego o jakości kryptograficznej — identyfikator dający się przewidzieć podważa cały mechanizm.
Indeksy i wydajność zapytań
Trzy indeksy odpowiadają weryfikacji sesji, wyszukiwaniu po użytkowniku i identyfikacji wiersza.
| Indeks | Kolumny | Rodzaj |
|---|---|---|
LOGIN_ACH | LOGIN, ACH | zwykły |
PK__users_ws | ID_USERS_WS | klucz główny |
SESSIONID | SESSIONID | unikalny |
Indeks na kolumnie SESSIONID jest unikalny i obsługuje operację wykonywaną najczęściej ze wszystkich w tej tabeli — sprawdzenie sesji przy każdym żądaniu. Indeks LOGIN_ACH służy czemu innemu: pozwala unieważnić wszystkie aktywne sesje danego użytkownika jedną operacją, co przydaje się przy podejrzeniu przejęcia konta.
Dobór czasu życia sesji i utrzymanie tabeli
Dwie decyzje przesądzają o tym, czy mechanizm działa dobrze: jak długo żyje sesja i kto sprząta wygasłe wiersze.
| Zastosowanie | Sugerowany termin | Uzasadnienie |
|---|---|---|
| Aplikacja mobilna magazyniera | Kilka godzin | Odpowiada długości zmiany, nie wymusza ponownego logowania |
| Sklep internetowy pobierający stany | Kilkanaście minut | Program odnawia sesję automatycznie, nie ma kosztu dla człowieka |
| Panel kontrahenta | Kilkadziesiąt minut | Kompromis między wygodą a ryzykiem porzuconej sesji |
| Integracja jednorazowa | Kilka minut | Sesja potrzebna wyłącznie na czas jednej operacji |
Zasada ogólna: im mniej udziału człowieka w odnawianiu sesji, tym krótszy powinien być jej termin ważności.
Sprzątanie wygasłych wierszy bywa pomijane, bo nic się nie psuje — sesja po terminie i tak nie jest honorowana. Tabela rośnie jednak nadal, a przy integracji odnawiającej sesję co kilkanaście minut przyrost sięga tysięcy wierszy dziennie. Proste zadanie usuwające wpisy starsze niż doba rozwiązuje to raz na zawsze.
Jak korzystać z tabeli w praktyce
Przy obsłudze sesji usług sieciowych warto pamiętać o kilku rzeczach:
- Generuj identyfikatory sesji z generatora losowego o jakości kryptograficznej; wartość przewidywalna podważa cały mechanizm.
- Ustawiaj termin ważności możliwie krótki — im mniej udziału człowieka w odnawianiu sesji, tym krócej powinna żyć.
- Usuwaj wygasłe wiersze cyklicznym zadaniem; przy częstym odnawianiu przyrost sięga tysięcy wpisów dziennie.
- Korzystaj z indeksu
LOGIN_ACH, aby unieważnić wszystkie sesje użytkownika naraz przy podejrzeniu przejęcia konta. - Nie przekazuj identyfikatora sesji w adresie żądania; trafia wtedy do dzienników serwera i historii przeglądarki.
- Kontroluj liczbę równoległych sesji jednego konta — nagły wzrost bywa sygnałem, że poświadczenia zostały udostępnione.
Aktywne sesje w podziale na użytkowników, wraz z czasem pozostałym do wygaśnięcia:
SELECT LOGIN,
COUNT(*) AS SESJI,
MIN(KIEDY) AS NAJSTARSZA,
MAX(TERMIN) AS WYGASA_NAJPOZNIEJ,
DATEDIFF(MINUTE, GETDATE(), MAX(TERMIN)) AS MINUT_DO_KONCA
FROM dbo._users_ws
WHERE ACH <> 'X'
AND TERMIN > GETDATE()
GROUP BY LOGIN
ORDER BY SESJI DESC;
Konto z kilkudziesięcioma równoległymi sesjami zwykle oznacza integrację, która zakłada nową sesję przy każdym żądaniu zamiast korzystać z istniejącej — to marnotrawstwo, które łatwo poprawić po stronie klienta.
Warto też zaplanować, co się dzieje przy restarcie serwera. Sesje zapisane w tabeli przetrwają go bez uszczerbku, w odróżnieniu od tych trzymanych w pamięci aplikacji — i jest to zaleta tego rozwiązania. Ma ona jednak drugą stronę: po awarii, po której nie wiadomo, czy identyfikatory nie wyciekły, sesje pozostają ważne. Procedura postępowania po incydencie powinna więc obejmować unieważnienie wszystkich aktywnych wierszy, a nie tylko zmianę haseł.
Sesje usług sieciowych są mechanizmem, który działa niezauważalnie i psuje się równie cicho. Zbyt długi termin ważności nie objawia się niczym, dopóki ktoś nie przechwyci identyfikatora; brak sprzątania — dopóki tabela nie urośnie do milionów wierszy. Obie rzeczy warto ustawić raz, przy uruchomieniu integracji.
Powiązane tabele i dokumentacja
Sesje usług sieciowych łączą się z kontami i danymi dostępowymi opisanymi poniżej: