Отслеживание истечения срока действия сессий

Ваше приложение всегда завершает работу с сессией после определенного периода бездействия со стороны пользователя, и вы хотите помочь пользователю сориентироваться, сколько времени осталось до того, как приложение аннулирует их регистрацию.

Решение

Создадим контроллер BankAccountController которая приводит к завершению работы с сессией по истечении десятиминутной пасивности:

  1. class BankAccountController < ApplicationController
  2. before_filter :update_activity_time, :except => :session_expiry
  3.  
  4. def update_activity_time
  5. session[:expires_at] = 10.minutes.from_now
  6. end
  7.  
  8. def session_expiry
  9. @time_left = (session[:expires_at] - Time.now).to_i
  10. unless @time_left > 0
  11. reset_session
  12. render ‘/signin/redirect’
  13. end
  14. end
  15.  
  16. end

Практически перед каждым запросом в нашем приложении мы вызываем метод фильтра update_activity_time. Этот фильтр устанавливает время существования пользовательской сессии на основе периода, прошедшего со времени последнего появления активности со стороны пользователя.

В фильтре, запускающем метод update_activity_time, мы не запускаем действие session_expiry. Если вы посмотрите на простое представление, созданного для этого контроллера index.rhtml, то поймете, почему:

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
  5. <title>Session</title>
  6. <%= javascript_include_tag :defaults %>
  7. </head>
  8. <body>
  9. <div id="header"></div>
  10. <%= periodically_call_remote :url => {
  11. :action => ‘session_expiry’ },
  12. :update => ‘header’ %>
  13.  
  14. <div id="body">Тут все приложение.</div>
  15. </body>
  16. </html>

Используя метод periodically_call_remote(), мы вызываем действие session_expiry() (по умолчанию каждые 10 секунд), помещая содержимое действия в первоначально пустой <div>-тег, имеющий идентификатор header. Если действие сессии еще не истекло, действие session_expiry() отправляет собственное представление (session_expiry.rhtml):

  1. <% if @time_left < 1.minute %>
  2. <span style="color:red; font-weight:bold;">
  3. До завершения работы сесии осталось (в сек.) - <%= @time_left %>
  4. </span>
  5. <% end %>

Если работа сессии должна завершится менее чем через минуту, представление session_expiry отобразит жирным шрифтом и красным цветом предупреждение, обновляемое каждые десять секунд.

Когда сессия должна завершить работу, session_expiry() перезапустит сессию и вызовет RJS-шаблон, а затем перенаправит браузер по URL, который соответствует окну идентификации пользователя приложения(redirect.rjs):

  1. page << "window.location = ‘#{signin_url}’;"

Почему используем перенаправление через JavaScript? Почему не стандартный redirect_to()? Получая от Ajax-запроса код ответа 302 HTTP, браузеры не сделают полноценное перенаправление. Поэтому мы и использовали RJS для генерации перенаправления.

Вот и все. Удачи в программировании!

20. сентября 2008 by Alexey Vasiliev
Categories: Ajax, javascript, Ruby on Rails | Tags: , , | Один комментарий

One Comment

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