что такое идентификатор сессии
Что такое идентификатор сессии
Добрый день! Уважаемые читатели и гости IT блога Pyatilistnik.org. В прошлый раз мы с вами разобрали, как сделать таймер выключения компьютера. Сегодня я хочу вас научить определять ID (Уникальный идентификатор) и номер сеанса пользователя на терминальных столах. Уметь, это нужно, для решения ситуаций, когда такой сеанс зависает и пользователь не может работать и переключиться на другую ноду RDS фермы, так как посредники подключений видят, что у него есть активная сессия. Думаю. что мой опыт, описанный в статье окажется вам полезным.
Что такое ID сеанса
Когда пользователь входит на компьютер с включенными службами удаленных рабочих столов, для него запускается сеанс. Каждый сеанс идентифицируется уникальным идентификатором сеанса. Каждый такой сеанс ассоциируется с интерактивной оконной станцией (interactive window station) «WinSta0»; поэтому каждый сеанс связан со своей собственной оконной станцией «WinSta0». Для каждой оконной станции имеется три стандартных рабочих стола: рабочий стол Winlogon, рабочий стол с заставкой и интерактивный рабочий стол.
Когда пользователь выходит с сервера удаленных рабочих столов (RDC), то сеанс, который клиент имеет на сервере узла сеансов удаленных рабочих столов (ранее назывался сервер терминалов), удаляется. Однако если сеанс консоли служб удаленных рабочих столов не смог завершится, то оконные станции, связанные с сеансом консоли, не удаляются, все процессы продолжают висеть. Это влияет на поведение приложений в среде служб удаленных рабочих столов, когда они настроены для работы в контексте безопасности интерактивного пользователя, также известного как режим активации объекта «RunAs Interactive User». Вот тогда, то и выявляется ID сеанса, чтобы его грохнуть.
Методы определения ID сеанса пользователя RDP
Существует несколько методов, которые могут вам помочь определить номер сеанса и его ID на терминальных серверах и RDS фермах.
Определение ID сеанса через quser
И так у меня есть RDS ферма состоящая из хостов с Windows Server 2012 R2, в базе Active Directory есть пользователь Барбоскин Геннадий Викторович. Данный пользователь вошел на терминал, работал, но по какой-то причине он завис и чтобы корректно разлогинить его сессию нам необходимо вычислить ее номер сеанса и уникальный идентификатор. Попробуем это выполнить через утилиту quser.
Вы можете использовать эту команду, чтобы выяснить, вошел ли конкретный пользователь на конкретный сервер Session Host. Команда возвращает:
Откройте командную строку cmd, лучше в режиме администратора и введите команду:
У вас будет выведен список всех текущих сессий на вашем терминальном сервере.Если пользователей много, то сложно сразу найти нужного, так как все идет не по алфавиту. Ранее я вам показывал, как фильтровать вывод результатов в командной строке Windows, там была команда findstr. Вводим команду:
В итоге я вижу, что номер сеанса rdp-tcp#24 и его ID 45, статус активно, это означает, что человек работает. Видно его время входа. Тот же результат можно получить и вот такой конструкцией:
Вы наверное спросите, почему сразу так не ввели, все просто, я лишь еще раз напомнил вам, о фильтрации в cmd, которая работает почти с любой командой, так сказать универсальный ключ.
Так же есть возможность запустить для конкретного сервера, для этого есть ключ /server
Определение ID сеанса через qwinsta
Для того, чтобы получить номер сеанса с ID, введите в командной строке:
Утилита выведет список всех авторизованных в системе пользователей, из полезной информации вы получите:
Чтобы вывести определенного пользователя, введите команду:
Как узнать id пользователя через диспетчер задач
Покажу и графический метод. который позволяет вам получать ID и номер сеанса на терминальных столах. Откройте диспетчер задач и перейдите на вкладку «Пользователи». У вас будет отображен список сотрудников. Тут для удобства их можно выстроить по алфавиту. Все хорошо, но нет ID и номера сеанса.
Чтобы включить отображение нужных нам столбцов, вам необходимо щелкнуть правым кликом на область с именем столбцов. В контекстном меню поставьте галки на «Код» и «Сеанс».
В итоге у вас теперь появилась возможность легко просматривать идентификационный код сеанса и имя сеанса, в моем примере, это RDP-Tcp#24.
Как узнать id пользователя через query session
Получение информации о сеансе через Get-TerminalSession
PowerShell не зря называют могучим, он поистине может все. К сожалению родных командлетов, которые бы заменяли утилиты командной строки нет, но есть возможность установить дополнительные, из репозитория. Речь пойдет, о сборнике «PowerShell Community Extensions» (Pscx 3.2.2). Данный сборник включаем в себя огромный комплекс командлетов, нас будет интересовать Get-TerminalSession.
Установка «PowerShell Community Extensions» очень проста и выполняется одной командой. Перед установкой Pscx 3.2.2, вам необходимо обновить ваш PowerShell хотя бы до версии 5.1. Далее запускаете оболочку PowerShell от имени администратора и вводите команду:
Про сам сборник вы можете почитать по ссылке (https://www.powershellgallery.com/packages/Pscx/3.2.2)
Получение информации о сеансе через Get-TSSession
Модуль PSTerminalServices, так же позволяет взаимодействовать с терминальными профилями В состав PSTerminalServices входят вот такие командлеты:
Скачать PSTerminalServices вы можете по ссылке https://github.com/imseandavis/PSTerminalServices, там будет MSI пакет, если его уже по какой-то причине не будет, то можете загрузить PSTerminalServices по ссылке слева.
Установка PSTerminalServices проста до безобразия. На первом экране нажимаем «Next».
При необходимости изменяем путь установки данного модуля.
Для продолжения нажимаем «Install»
Установка модуля завершена.
Теперь, чтобы модуль запускался вам нужно разрешить запуск скриптов, напоминаю, что для текущего пользователя, это можно сделать вот так:
Далее проверьте командой, что модуль PSTerminalServices доступен в системе, выполните:
Далее импортируем модуль и запускаем его:
На выходе вы получаете информацию, о всех ваших сеансах пользователей на терминальном столе
Как использовать сессии и переменные сессий в PHP
Дата публикации: 2018-10-19
От автора: обработка сессии PHP является ключевой концепцией языка, которая позволяет сохранять информацию пользователя на всех страницах веб-сайта или приложения. В этом посте вы узнаете основы обработки сессий в PHP.
Мы начнем с пояснения того, как работают сессии и как они связаны с файлами куки. Затем мы рассмотрим несколько фрагментов кода, демонстрирующих, как работать с сессиями. Вы узнаете, как создавать и удалять сессии и как изменять переменные сессии.
Что такое сессия в PHP?
Сессия — это механизм для сохранения информации на разных веб-страницах для идентификации пользователей при навигации по сайту или приложению. Вам интересно, почему сессии необходимы для веб-сайта? Чтобы понять, для чего необходимы сессии, нам нужно рассмотреть, как работает протокол HTTP.
Протокол HTTP — это протокол без учета состояния, что означает, что сервер не может запоминать конкретного пользователя между несколькими запросами. Например, при доступе к веб-странице сервер отвечает за предоставление содержимого запрашиваемой страницы. Поэтому, когда вы обращаетесь к другим страницам одного и того же веб-сайта, веб-сервер интерпретирует каждый запрос отдельно, как если бы они не были связаны друг с другом. Серверу не известно, что каждый запрос исходит от одного и того же пользователя. Следующая диаграмма иллюстрирует протокол HTTP.
Бесплатный курс по PHP программированию
Освойте курс и узнайте, как создать динамичный сайт на PHP и MySQL с полного нуля, используя модель MVC
В курсе 39 уроков | 15 часов видео | исходники для каждого урока
В этой модели, если вы хотите отображать информацию пользователя, вам нужно будет аутентифицировать пользователя в каждом запросе. Представьте, что вам нужно было бы вводить имя пользователя и пароль на каждой странице, на которой была представлена ваша информация о профиле! Да, это было бы вообще не практичным, и именно здесь на сцену выходят сессии.
Сессия позволяет обмениваться информацией на разных страницах одного сайта или приложения, что помогает поддерживать состояние. Это позволяет серверу знать, что все запросы исходят от одного и того же пользователя, что дает возможность отображать информацию и настройки пользователя.
Поток авторизации с помощью сессий и файлов куки
Давайте кратко рассмотрим общий поток авторизации, чтобы понять, что происходит за кулисами.
Пользователь открывает страницу авторизации на сайте.
После отправки данных формы входа сервер на другом конце аутентифицирует запрос, проверив введенные учетные данные.
Если учетные данные, введенные пользователем, действительны, сервер создает новую сессию. Сервер генерирует уникальное случайное число, которое называется идентификатором сессии. Он также создает новый файл, который используется для хранения информации, относящейся к сессии.
Затем пользователю передается идентификатор сессии, а также любой запрошенный ресурс. За кулисами этот идентификатор сеанса отправляется в файле куки PHPSESSID в заголовке ответа.
Когда браузер получает ответ от сервера, он находит его в заголовке файла куки PHPSESSID. Если куки разрешены браузером, он сохранит этот файл PHPSESSID, в котором хранится идентификатор сессии, переданный сервером.
Таким образом, пользовательские данные сохраняются для нескольких запросов, и пользователь остается авторизованным на протяжении всей сессии. На следующей диаграмме показано, как протокол HTTP работает с сессиями.
Теперь, когда мы кратко рассмотрели сессии, мы возьмем несколько практических примеров, чтобы продемонстрировать, как создавать и изменять переменные сессии.
Как начать сессию
В этом разделе мы рассмотрим, как в PHP начать сессию. Каждый раз, когда вы хотите работать с переменными сессии, вам необходимо убедиться, что сессия уже запущена. Есть несколько способов начать сессию в PHP.
Использовать функцию session_start
Это метод, который вы встретите чаще всего, когда сессия запускается функцией session_start.
Термин: Идентификатор сессии
Идентификатор сессии – это переменная сессии, посредством которой происходит идентификация клиента (браузера). Этот уникальный идентификатор присваивается клиенту (браузеру) с той целью, чтобы он вернул ее при следующем запросе. По умолчанию в PHP идентификатор сессии обозначается как PHPSESSID.
Для каждого пользователя идентификатор сессии является уникальным и постоянным на весь сеанс работы. Если идентификатор передается неправильно, либо не передается совсем, это приведет к тому, что при каждом последующем обращении к сайту, PHP по умолчанию будет подставлять к ссылкам новый PHPSESSID.
В частности, поисковики, индексирующие сайты, воспринимают ссылку с измененной переменной PHPSESSID как новую и индексируют ее повторно, тем самым переполняя поисковую базу дубликатами страниц и увеличивая нагрузку на сервер.
Передача идентификатора сессии
В настройках могут быть включены либо оба свойства, либо одно из них. Если включено первое (передача в куках), то при старте сессии клиенту устанавливаются cookies. Браузер при каждом последующем запросе возвращает эти cookies и PHP получает идентификатор сессии. Если включено второе, то куки не устанавливаются, и PHP дописывает к каждой ссылке и форме передачу идентификатора сессии.
В целях оптимизации сайта рекомендуется выключать второе свойство, оставляя только первое. Это позволит избежать многократной индексации поисковиками одной и той же страницы.
session_id
(PHP 4, PHP 5, PHP 7, PHP 8)
session_id — Получает и/или устанавливает идентификатор текущей сессии
Описание
session_id() используется для получения или установки идентификатора текущей сессии.
Константа SID также может быть использована для получения текущего имени и идентификатора сессии в виде строки, подходящей для добавления в URL-адреса. Смотрите также Работа с сессиями.
Список параметров
Замечание: При использовании сессионных cookie, указание id для session_id() приводит к тому, что при вызове session_start() всегда будут отправлены новые cookie, независимо от того, совпадает ли идентификатор текущей сессии с вновь установленным.
Возвращаемые значения
Список изменений
Смотрите также
User Contributed Notes 22 notes
It may be good to note that PHP does not allow arbitrary session ids. The session id validation in PHP source is defined in ext/session/session.c in the function php_session_valid_key:
To put it short, a valid session id may consists of digits, letters A to Z (both upper and lower case), comma and dash. Described as a character class, it would be [-,a-zA-Z0-9]. A valid session id may have the length between 1 and 128 characters. To validate session ids, the easiest way to do it use a function like:
?>
session_id() itself will happily accept invalid session ids, but if you try to start a session using an invalid id, you will get the following error:
Warning: session_start(): The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and ‘-,’
I was perplexed by inconsistent results with the session ID depending on whether I retrieve it using SID, COOKIE, or session_id(). I have found that session_id() is the most reliable method, whereas SID and COOKIE[«PHPSESSIONID»] are sometimes undefined.
I used this simple script to quickly test the problem on my servers:
If I insert the session_regenerate_id() method that jeff_zamrzla gives below the refresh the page, I get a new session_id() but the COOKIE value is initially the prior session_id() until I hit refresh a second time. So again, session_id() proves to be the most reliable method.
It’s probably not a bug since I found the behaviour to be consistent in PHP versions 5.2.14, 5.3.3 and 5.3.4, but I can’t figure what I’m missing and hopefully this will help others who run into this.
session_id() URL-decodes the session value. For example let’s say we use setcookie() to push a cookie down to a web browser. When the browser makes the next page request the browser sends the cookie back up to us with headers like this: Cookie: PHPSESSID=enGHumY%2C-2De-F-TDzNHVmE%2ChY5;
If we use session_id() to read the cookie it will output a value of this: enGHumY,-2De-F-TDzNHVmE,hY5
The two values don’t match! Use either setrawcookie() or URL encode if you wish to match the original value.
This can looks obvious, but as me, you can spend some hours to make a simple session work between different browsers and devices. These are the basics for me, but you can build upon.
About the note from Cybertinus :
The following test doesn’t work, the code following is always executed :
if(! session_id ())
<
// Always executed even if there’s already an opened session
>
Note that Firefox and Mozilla use the same process for launching new windows or tabs, they will pick up the same session id as the previous windows until the parent process dies or is closed. This may cause undesired results if the session id is stored in a db and checked, a solution is to check at the new entry point (new tab or window if the user went back to the index page) for an existing session. If a session id exists and a new one is required use something like:
Gosh, took a LOOONG time to figure this one out! If you have suhosin built into your PHP and can’t get sessions to work after changing the session id through session_id(), try turning off suhosin’s session encryption option in php.ini with:
In response to simon at quo dot com dot au:
The PHPSESSID is produced using an hash function. By default, it uses MD5 which produces 128 bits long (i.e: 16 bytes long) hashes.
But, since some bytes’ values may not be used in the HTTP header, PHP outputs the hash in its hexadecimal representation, thus resulting in a 32 bytes long text.
Starting with PHP 5.0, you can change the hash function used (by setting «session.hash_function» to whatever function you want to use in php.ini).
You may for example set it to 1 to switch to SHA-1 which produces 160 bits (20 bytes) long hashes.
Please also note that another setting was introduced in PHP 5 (session.hash_bits_per_character) which sort of «compresses» the hash. Thus, resulting in what seems to be a shorter hash.
This feature helps you improve your application’s security by producing IDs that are harder to prodict for a malicious attacker.
The higher you set session.hash_bits_per_character the shorter your session_id will become by using more bits per character. The possible values are 4, 5, or 6.
When using sha-1 for hashing (by setting ini_set(‘session.hash_function’, 1) the following session string lengths are produced by the three session.hash_bits_per_character settings:
It would seem desirable to use sha-l with 5 bits_per_character because this will emulate a standard 32 character md5 string and make a would-be attacker think that is what you’re hashing with.
I had a lot of trouble with session_regenerate_id() as it did not regenerate. Session_id() stayed the same no matter what (unless closing the window). I wanted to have different sid and empty vars for each session/page meeting a condition for security reasons. Finally, this worked:
The documentation for session_id is incomplete when it says:
«For example, the file session handler only allows characters in the range a-z, A-Z and 0-9!».
It is untrue when changing the default for the session.hash_bits_per_character as Colin said. session_id may therefore contain «-» and «,».
Get a shared session.
Sometimes is good can interchange messages and vars between one session and another, but PHP dont support this. I create this script that allows with session_id() change from current session to shared session (this is, info with scope to all sessions) for read and write info and back in to user session. The code:
PHP для начинающих. Сессия
Начну с сессий — это один из самых важных компонентов, с которыми вам придется работать. Не понимая принципов его работы — наворотите делов. Так что во избежание проблем я постараюсь рассказать о всех возможных нюансах.
Но для начала, чтобы понять зачем нам сессия, обратимся к истокам — к HTTP протоколу.
HTTP Protocol
Изначально подразумевали, что по этому протоколу будет только HTML передаваться, отсель и название, а сейчас чего только не отправляют и =^.^= и(•_ㅅ_•)
Чтобы не ходить вокруг да около, давайте я вам приведу пример общения по HTTP протоколу.
Вот пример запроса, каким его отправляет ваш браузер, когда вы запрашиваете страницу http://example.com :
А вот пример ответа:
Это очень упрощенные примеры, но и тут можно увидеть из чего состоят HTTP запрос и ответ:
Т.е. если украсть cookie из вашего браузера, то можно будет зайти на вашу страничку в facebook от вашего имени? Не пугайтесь, так сделать нельзя, по крайней мере с facebook, и дальше я вам покажу один из возможных способов защиты от данного вида атаки на ваших пользователей.
Давайте теперь посмотрим как изменятся наши запрос-ответ, будь там авторизация:
Метод у нас изменился на POST, и в теле запроса у нас передаются логин и пароль. Если использовать метод GET, то строка запроса будет содержать логин и пароль, что не очень правильно с идеологической точки зрения, и имеет ряд побочных явлений в виде логирования (например, в том же access.log ) и кеширования паролей в открытом виде.
Как можно заметить, заголовки отправляемые браузером (Request Headers) и сервером (Response Headers) отличаются, хотя есть и общие и для запросов и для ответов (General Headers)
Сервер узнал нашего пользователя по присланным cookie, и дальше предоставит ему доступ к личной информации. Так, ну вроде с сессиями и HTTP разобрались, теперь можно вернутся к PHP и его особенностям.
PHP и сессия
Я надеюсь, у вас уже установлен PHP на компьютере, т.к. дальше я буду приводить примеры, и их надо будет запускать
Вот вам статейка на тему PHP is meant to die, или вот она же на русском языке, но лучше отложите её в закладки «на потом».
Перво-наперво необходимо «стартовать» сессию — для этого воспользуемся функцией session_start(), создайте файл session.start.php со следующим содержимым:
Запустите встроенный в PHP web-server в папке с вашим скриптом:
Запустите браузер, и откройте в нём Developer Tools (или что там у вас), далее перейдите на страницу http://127.0.0.1:8080/session.start.php — вы должны увидеть лишь пустую страницу, но не спешите закрывать — посмотрите на заголовки которые нам прислал сервер:
Там будет много чего, интересует нас только вот эта строчка в ответе сервера (почистите куки, если нет такой строчки, и обновите страницу):
Увидев сие, браузер сохранит у себя куку с именем `PHPSESSID`:
PHPSESSID — имя сессии по умолчанию, регулируется из конфига php.ini директивой session.name, при необходимости имя можно изменить в самом конфигурационном файле или с помощью функции session_name()
И теперь — обновляем страничку, и видим, что браузер отправляет эту куку на сервер, можете попробовать пару раз обновить страницу, результат будет идентичным:
Итого, что мы имеем — теория совпала с практикой, и это просто отлично.
Обновляем страничку и видим время сервера, обновляем ещё раз — и время обновилось. Давайте теперь сделаем так, чтобы установленное время не изменялось при каждом обновлении страницы:
Обновляем — время не меняется, то что нужно. Но при этом мы помним, PHP умирает, значит данную сессию он где-то хранит, и мы найдём это место…
Всё тайное становится явным
В вашей конфигурации путь к файлам может быть не указан, тогда файлы сессии будут хранится во временных файлах вашей системы — вызовите функцию sys_get_temp_dir() и узнайте где это потаённое место.
Так, идём по данному пути и находим ваш файл сессии (у меня это файл sess_dap83arr6r3b56e0q7t5i0qf91 ), откроем его в текстовом редакторе:
Как видим — вот оно наше время, вот в каком хитром формате хранится наша сессия, но мы можем внести правки, поменять время, или можем просто вписать любую строку, почему бы и нет:
Так, что мы ещё не пробовали? Правильно — украсть «печеньки», давайте запустим другой браузер и добавим в него теже самые cookie. Я вам для этого простенький javascript написал, скопируйте его в консоль браузера и запустите, только не забудьте идентификатор сессии поменять на свой:
Вот теперь у вас оба браузера смотрят на одну и туже сессию. Я выше упоминал, что расскажу о способах защиты, рассмотрим самый простой способ — привяжем сессию к браузеру, точнее к тому, как браузер представляется серверу — будем запоминать User-Agent и проверять его каждый раз:
Ключевое слово в предыдущем абзаце похоже, в реальных проектах cookies уже давно «бегают» по HTTPS протоколу, таким образом никто их не сможет украсть без физического доступа к вашему компьютеру или смартфону
Стоит упомянуть директиву session.cookie-httponly, благодаря ей сессионная кука будет недоступна из JavaScript’a. Кроме этого — если заглянуть в мануал функции setcookie(), то можно заметить, что последний параметр так же отвечает за HttpOnly. Помните об этом — эта настройка позволяет достаточно эффективно бороться с XSS атаками в практически всех браузерах.
По шагам
А теперь поясню по шагам алгоритм, как работает сессия в PHP, на примере следующего кода (настройки по умолчанию):
А есть ли жизнь без «печенек»?
PHP может работать с сессией даже если cookie в браузере отключены, но тогда все URL на сайте будут содержать параметр с идентификатором вашей сессии, и да — это ещё настроить надо, но оно вам надо? Мне не приходилось это использовать, но если очень хочется — я просто скажу где копать:
А если надо сессию в базе данных хранить?
Отдельно замечу, что не надо писать собственные обработчики сессий для redis и memcache — когда вы устанавливаете данные расширения, то вместе с ними идут и соответствующие обработчики, так что RTFM наше всё. Ну и да, обработчик нужно указывать до вызова session_start() 😉
Когда умирает сессия?
За время жизни сессии отвечает директива session.gc_maxlifetime. По умолчанию, данная директива равна 1440 секундам (24 минуты), понимать её следует так, что если к сессии не было обращении в течении заданного времени, то сессия будет считаться «протухшей» и будет ждать своей очереди на удаление.
Интересен другой вопрос, можете задать его матёрым разработчикам — когда PHP удаляет файлы просроченных сессий? Ответ есть в официальном руководстве, но не в явном виде — так что запоминайте:
Самая тривиальная ошибка
Ошибка у которой более полумиллиона результатов в выдаче Google:
Cannot send session cookie — headers already sent by
Cannot send session cache limiter — headers already sent
Для получения таковой, создайте файл session.error.php со следующим содержимым:
Во второй строке странная «магия» — это фокус с буфером вывода, я ещё расскажу о нём в одной из следующих статей, пока считайте это лишь строкой длинной в 4096 символов, в данном случае — это всё пробелы
Для проверки полученных знаний, я хочу, чтобы вы реализовали свой собственный механизм сессий и заставили приведенный код работать:
Блокировка
Ещё одна распространённая ошибка у новичков — это попытка прочитать файл сессии пока он заблокирован другим скриптом. Собственно, это не совсем ошибка, это недопонимание принципа блокировки 🙂
Но давайте ещё раз по шагам:
«Воткнутся» в данную ошибку очень легко, создайте два файла:
Есть пару вариантов, как избежать подобного явления — «топорный» и «продуманный».
«Топорный»
Использовать самописный обработчик сессий, в котором «забыть» реализовать блокировку 🙂
Чуть лучше вариант, это взять готовый и отключить блокировку (например у memcached есть такая опция — memcached.sess_locking) O_o
Потратить часы на дебаг кода в поисках редко всплывающей ошибки…
«Продуманный»
Куда как лучше — самому следить за блокировкой сессии, и снимать её, когда она не требуется:
— Если вы уверенны, что вам не потребуется вносить изменения в сессионные данные используйте опцию read_and_close при старте сессии:
Таким образом, блокировка будет снята сразу по прочтению данных сессии.
— Если вам таки нужно вносить изменения в сессию, то после внесения оных закрывайте сессию от записи:
В заключение
В этой статье вам дано семь заданий, при этом они касаются не только работы с сессиями, но так же познакомят вас с MySQL и с функциями работы со строками. Для усвоения этого материала — отдельной статьи не нужно, хватит и мануала по приведенным ссылкам — никто за вас его читать не будет. Дерзайте!