#coldfusion
#coldfusion
Вопрос:
Я хочу принудительно завершить сеанс через 30 минут независимо от активности. Первое, о чем я подумал, было это (непроверенное):
function onApplicationStart() application.sessionLife = 30;
function onSessionStart() session.timeStarted = now();
function onRequestStart() {
if ( dateDiff("n", session.timeStarted, now()) > application.sessionLife)
structClear(session);
}
Какие другие способы доступны для принудительного завершения сеанса?
Очевидным является файл cookie сеанса, срок действия которого истекает через 30 минут. Но я не уверен, прослушивают ли сеансовые файлы cookie sessionTimeout sessting или нет.
Обновление Я только что узнал, что StructClear() не завершает сеанс. Так что, я думаю, я должен просто истечь срок действия файлов cookie.
Комментарии:
1. Вы захотите использовать StructClear(session), а не StructDelete. StructDelete предназначен для удаления одного ключа из структуры.
2. Шон, хотя ты прав, structClear() не завершает сеанс. Я только что узнал об этом секунду назад. bennadel.com/blog /…
3. Да, я не предполагал, что это произойдет (отсюда и мое использование комментария вместо ответа), я просто хотел указать, что ваш исходный пример кода потерпит неудачу, если оставить все как есть.
Ответ №1:
Как обычно, Бен Надел уже опубликовал ответ в блоге…
http://www.bennadel.com/blog/1847-Explicitly-Ending-A-ColdFusion-Session.htm
Есть несколько вариантов, некоторые из которых вполне безопасны, другие используют скрытые методы, которые не гарантированы в будущих версиях ColdFusion или других движков CFML. Вы можете заметить, что я получаю упоминание в его сообщении, поскольку я люблю возиться с этими скрытыми методами. Но если вы хотите сделать все правильно (более надежное доказательство на будущее / доказательство переключения двигателя), я бы предложил альтернативные методы Бена.
Редактировать
Чуть не забыл, я создал функцию для остановки текущего сеанса с помощью другого метода (не упомянутого в сообщении в блоге Бена Наделя). Это все еще недокументированная функция, но это улучшение, поскольку она мгновенно останавливает сеанс, вместо того, чтобы устанавливать его на 1 секунду до истечения времени ожидания.
http://misterdai.wordpress.com/2010/06/15/cf-sessionstop-ending-a-cf-session/
Дальнейшее редактирование
Просто кратко объясняю различные методы на случай, если связанные сайты когда-либо исчезнут.
Чтобы обобщить способы остановки сеанса в его треках…
- Установите для sessionTimeout значение 1 секунда.
- Отметьте целевой сеанс (например, session.remove = true)
- Обнаружение и установка низкого времени ожидания (application.cfc)
if (StructKeyExists(session, 'remove') And aession.remove) {
this.sessionTimeout = CreateTimeSpan(0, 0, 0, 1);
} - Удалите связь между клиентом и сеансом, удалив файлы cookie CFID / CFTOKEN.
- Аналогично приведенному выше, но с использованием session.setMaxInactiveInterval(1)
- Недокументировано, работает, но может меняться без предварительного уведомления между версиями.
- Более гибкий, не требует наличия кода в файле application.cfc.
- Все равно придется удалять файлы cookie.
- Заставьте ColdFusion немедленно удалить сеанс.
- Больше использования недокументированных функций, которые могут прерываться между версиями.
- Может использоваться где угодно, не нужно беспокоиться о файлах cookie или таймаутах в одну секунду.
Код для подхода 3…
<cffunction name="sessionStop" output="false">
<cfset var local = StructNew() />
<cfif Not StructKeyExists(application, 'applicationName')>
<cfthrow message="Application.applicationName is missing." />
</cfif>
<cftry>
<cfset local.sid = session.cfid amp; '_' amp; session.cftoken />
<cfset local.jTracker = CreateObject('java', 'coldfusion.runtime.SessionTracker') />
<cfset local.jTracker.cleanUp(application.applicationName, local.sid) />
<cfcatch type="any">
<cfthrow message="Error stopping session, may not exist." />
</cfcatch>
</cftry>
</cffunction>
Комментарии:
1. Я сделал! На самом деле я тоже читал это сообщение в блоге, когда вы опубликовали ответ. Хороший материал! Приветствия!
2. Когда блог г-на Наделя исчезнет или изменит структуру каталогов, этот ответ не будет иметь никакого значения. Как насчет хотя бы обобщения ответа?
3. Хорошо, я обновил краткое описание подходов. Должно быть достаточно, чтобы люди могли разработать необходимый код 🙂
4. @MisterDai Молодец! кстати: docs.oracle.com/javaee/1.3/api/javax/servlet/http /…
5. Что происходит, когда вы получаете сообщение об ошибке, что метод cleanUp() не может быть найден? Это отлично работает на моем старом сервере, но не на новом. Есть ли настройка, которую мне нужно включить?
Ответ №2:
Я не думаю, что вы хотите использовать structClear() . Если я правильно помню, возникают проблемы, если ключи CFID и CFTOKEN удаляются из структуры СЕАНСА. Вот код, который мы используем для завершения сеанса:
<!--- Delete the session --->
<cfloop collection="#session#" item="skey">
<cfif NOT listFindNoCase("cfid,cftoken,sessionid,urltoken", skey)>
<cfset structDelete(session, skey) />
</cfif>
</cfloop>
<!--- Expire the CFID and CFTOKEN cookies to start a new session --->
<cfcookie name="cfid" expires="Now" />
<cfcookie name="cftoken" expires="Now" />
<!--- Expire the JSESSIONID cookie - only needed if J2EE sessions are used --->
<cfcookie name="jsessionid" expires="Now" />
Итак, мы удаляем все ключи из СЕАНСА, кроме CFID, CFTOKEN, SESSIONID и URLTOKEN, затем у нас истекает срок действия файлов cookie, которые идентифицируют сеанс. Когда это произойдет, CF должен создать новые файлы cookie и начать новый сеанс.