Отслеживание истечения срока действия сессий
Ваше приложение всегда завершает работу с сессией после определенного периода бездействия со стороны пользователя, и вы хотите помочь пользователю сориентироваться, сколько времени осталось до того, как приложение аннулирует их регистрацию.
Решение
Создадим контроллер BankAccountController которая приводит к завершению работы с сессией по истечении десятиминутной пасивности:
-
class BankAccountController < ApplicationController
-
before_filter :update_activity_time, :except => :session_expiry
-
-
def update_activity_time
-
session[:expires_at] = 10.minutes.from_now
-
end
-
-
def session_expiry
-
@time_left = (session[:expires_at] - Time.now).to_i
-
unless @time_left > 0
-
reset_session
-
render ‘/signin/redirect’
-
end
-
end
-
-
end
Практически перед каждым запросом в нашем приложении мы вызываем метод фильтра update_activity_time. Этот фильтр устанавливает время существования пользовательской сессии на основе периода, прошедшего со времени последнего появления активности со стороны пользователя.
В фильтре, запускающем метод update_activity_time, мы не запускаем действие session_expiry. Если вы посмотрите на простое представление, созданного для этого контроллера index.rhtml, то поймете, почему:
-
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-
<html>
-
<head>
-
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
-
<title>Session</title>
-
<%= javascript_include_tag :defaults %>
-
</head>
-
<body>
-
<div id="header"></div>
-
<%= periodically_call_remote :url => {
-
:action => ‘session_expiry’ },
-
:update => ‘header’ %>
-
-
<div id="body">Тут все приложение.</div>
-
</body>
-
</html>
Используя метод periodically_call_remote(), мы вызываем действие session_expiry() (по умолчанию каждые 10 секунд), помещая содержимое действия в первоначально пустой <div>-тег, имеющий идентификатор header. Если действие сессии еще не истекло, действие session_expiry() отправляет собственное представление (session_expiry.rhtml):
-
<% if @time_left < 1.minute %>
-
<span style="color:red; font-weight:bold;">
-
До завершения работы сесии осталось (в сек.) - <%= @time_left %>
-
</span>
-
<% end %>
Если работа сессии должна завершится менее чем через минуту, представление session_expiry отобразит жирным шрифтом и красным цветом предупреждение, обновляемое каждые десять секунд.
Когда сессия должна завершить работу, session_expiry() перезапустит сессию и вызовет RJS-шаблон, а затем перенаправит браузер по URL, который соответствует окну идентификации пользователя приложения(redirect.rjs):
-
page << "window.location = ‘#{signin_url}’;"
Почему используем перенаправление через JavaScript? Почему не стандартный redirect_to()? Получая от Ajax-запроса код ответа 302 HTTP, браузеры не сделают полноценное перенаправление. Поэтому мы и использовали RJS для генерации перенаправления.
Вот и все. Удачи в программировании!


Где то я это уже видел.