web-dev-qa-db-fra.com

Définition du délai d'expiration de la session dans Rails 3

Cela semble simple: j'essaye de faire expirer ma session Rails Active Record) après 2 minutes. Donc, après deux minutes, je veux que mes utilisateurs doivent se reconnecter.

Je suis juste en train de courir Rails server (c'est-à-dire WebBrick) sur ma machine de développement locale.

Je sais que c'est quelque chose à voir avec le code suivant dans config/initalizers/session_store.rb, mais je ne pense pas l'avoir bien compris:

CodedOn::Application.config.session_store :active_record_store

CodedOn::Application.configure do
    config.action_controller.session = {:expire_after => 2.minutes}
end

Cela ne semble pas fonctionner, ou du moins ma session ne semble pas expirer. Je ne peux pas trouver grand-chose sur la manière Rails 3 de faire cela car je sais que les choses ont changé de Rails 2.x.

Est-ce que quelqu'un peut m'aider?

45
Ciaran Archer

Je pense que vous devrez le faire manuellement car le magasin de disques actif n'implémente pas l'option expire_after. Donc, dans votre (je suppose) avant le filtre, vous devez faire ceci:

def authenticate
  if session[:logged_in]
    reset_session if session[:last_seen] < 2.minutes.ago
    session[:last_seen] = Time.now
  else
    ... authenticate
    session[:last_seen] = Time.now
  end
end

Évidemment, ce n'est pas complet, mais cela devrait vous donner l'idée de base.

[~ # ~] mise à jour [~ # ~] :

Il semble que la fonctionnalité IS présente dans Rails depuis la version 2.3. J'ai trouvé le code pertinent ici . Ceci est AbstractStore qui devrait servir de classe de base pour toutes les classes dérivées. Ainsi, comme le suggère dadooda, ce qui suit devrait fonctionner:

Some::Application.config.session_store :active_record_store, {
  expire_after: 24.hours,
}
46
moritz

Je l'ai fait de manière simple, vous pouvez essayer ceci:

Dans ton config/initializers/session_store.rb faites juste ceci:

Yourapp::Application.config.session_store :cookie_store, 
                                             :key => "_yourapp_session",
                                             :expire_after => 2.minutes

Cela fonctionne bien pour moi, l'espoir fonctionne aussi pour vous.

41
Ravindra

Tu dois le faire manuellement. Voici un exemple de création d'une méthode de classe pour les sessions ActiveRecord. Vous pouvez utiliser Rufus-Scheduler et/ou DelayedJob pour l'appeler régulièrement.

class Session < ActiveRecord::Base
  def self.sweep(time = 1.hour)
    if time.is_a?(String)
      time = time.split.inject { |count, unit| count.to_i.send(unit) }
    end

    delete_all "updated_at < '#{time.ago.to_s(:db)}' OR created_at < '#{2.days.ago.to_s(:db)}'"
  end
end

Plus d'informations sur pourquoi c'est important: http://guides.rubyonrails.org/security.html#session-expiry

4
m33lky

mosch dit:

Je pense que vous devrez le faire manuellement car le magasin de disques actif n'implémente pas l'option expire_after.

Il semble que ce ne soit plus ainsi. :expire_after a fonctionné pour moi dans Rails 3.2.11:

Some::Application.config.session_store :active_record_store, {
  key: "some_session_id",
  domain: ".isp.com",
  expire_after: 24.hours,
}

Le cookie se prolonge automatiquement après chaque demande vers l'application. La session persiste à travers les sorties du navigateur.

J'ai fait l'astuce ci-dessus pour "globaliser" la session à travers le domaine pour une fonctionnalité SSO simple, semble fonctionner jusqu'à présent.

4
Alex Fortuna

Le délai d'expiration.

MAX_SESSION_TIME = 60 * 60

before_filter :prepare_session

def prepare_session

   if !session[:expiry_time].nil? and session[:expiry_time] < Time.now
      # Session has expired. Clear the current session.
      reset_session
   end

   # Assign a new expiry time, whether the session has expired or not.
   session[:expiry_time] = MAX_SESSION_TIME.seconds.from_now
   return true
end
2
regmiprem