Connexion automatique avec Rails?
-
20-09-2019 - |
Question
Je suis en train d'obtenir un système d'authentification simple avec le plug-in Restful-authentification Rails, et je me demandais comment cela fonctionne, b / c je ne peux pas sembler comprendre quelles sont les exigences pour les cookies, et comment faire de sorte que le navigateur se souvient toujours (pour 6 mois +).
Quelques questions:
1) Comment faites-vous des années Remember_Me pour le restful_authentication de rubis? Je ne peux pas sembler trouver un bon-liner pour résoudre ce problème ...
Si un utilisateur se connecte vers le haut et les chèques « Remember Me », comment l'application rails obtenir la session / cookies sans que l'utilisateur fait quoi que ce soit, mais d'aller à la page la prochaine fois qu'ils vont à la page, par exemple 3 mois plus tard?
2) Est-ce que je dois envoyer une sorte d'informations sur le serveur, comme leur adresse IP ou quelque chose? Qu'est-ce cookies[:auth_token]
, où est celle définie?
Le but est: Je ne veux pas qu'ils aient à entrer dans leur e-mail / mot de passe, comme la façon dont fonctionne StackOverflow:)
La solution
Voici ce que nous faisons (en grande partie pris du système authentifié) ... c'est la méthode du contrôleur qui gère la connexion que nous courons ...
def login
if logged_in?
flash[:notice] = "You are already logged in."
redirect_to "/" and return
end
unless request.post?
render :layout => 'task' and return
end
self.current_user = User.authenticate(params[:login], params[:password])
if logged_in?
if params[:remember_me].to_i == 1
self.current_user.remember_me
cookies[:auth_token] = {:domain => "#{DOMAIN}", :value => self.current_user.remember_token , :expires => self.current_user.remember_token_expires_at }
else
self.current_user.forget_me
cookies.delete(:auth_token, :domain => "#{DOMAIN}")
cookies[:auth_token] = nil
end
current_user.last_seen_at = Time.now
current_user.save
session[:notice] = "You logged in successfully"
flash[:notice] = "You logged in successfully"
redirect_back_or_default(:controller => 'dashboard') and return
#redirect_back_or_default(:controller => 'index', :action => 'index') and return
else
if $failed_login_counter.add_attempt(params[:login]) > MAXIMUM_LOGIN_ATTEMPTS
logger.info("login rate limiter kicking in, #{MAXIMUM_LOGIN_ATTEMPTS} login attempts failed")
redirect_to "/denied.html" and return
end
flash[:error] = "Unable to authenticate username and password"
render(:layout => 'task') and return
end
end
Et utiliser pour fermeture de session
def logout
current_user.last_seen_at = Time.now
current_user.save
self.current_user.forget_me if logged_in?
cookies.delete(:auth_token, :domain => "#{DOMAIN}")
reset_session
flash[:notice] = "You have been logged out."
#redirect_to :back
redirect_back_or_default(:controller => 'index', :action => 'index') and return
end
Alors - dans votre application.rb vous aurez besoin quelque chose comme:
before_filter :login_from_cookie
def login_from_cookie
return unless cookies[:auth_token] && !logged_in?
user = User.find_by_remember_token(cookies[:auth_token])
if user && user.remember_token?
user.remember_me
self.current_user = user
cookies[:auth_token] = { :domain => "#{DOMAIN}", :value => self.current_user.remember_token , :expires => self.current_user.remember_token_expires_at }
flash[:notice] = "#{self.current_user.login}, you have logged in successfully"
end
end
- dans votre modèle utilisateur ont des méthodes comme celle-ci:
# Encrypts some data with the salt.
def self.encrypt(password, salt)
Digest::SHA1.hexdigest("--#{salt}--#{password}--")
end
# Encrypts the password with the user salt
def encrypt(password)
self.class.encrypt(password, salt)
end
def remember_token?
remember_token_expires_at && Time.now.utc < remember_token_expires_at
end
# These create and unset the fields required for remembering users between browser closes
def remember_me
self.remember_token_expires_at = 2.weeks.from_now.utc
self.remember_token = encrypt("#{email}--#{remember_token_expires_at}")
save(false)
end
def forget_me
self.remember_token_expires_at = nil
self.remember_token = nil
save(false)
end
Autres conseils
Je suis honnêtement pas sûr aboout que la mise en œuvre particulière. Mais une méthode d'authentification commune RESTful est de passer d'une version hachée de l'utilisateur / mot de passe à chaque requête en en-tête. Vous pouvez également utiliser une valeur de cookie haché comme en-tête.
Je l'ai vu aussi des systèmes hybrides qui impliquent à la fois. Vous passez à la session, si vous le savez, en plus de l'utilisateur / passe. Ensuite, côté serveur si la session est valide, il l'utilise et peut mettre en cache la session -> relation utilisateur pour la performance. Si la session est invalide, il tente d'authentifier l'utilisateur à l'aide / passe.
Dans ce type de système que vous souhaitez passer la session de retour sur la réponse en-tête.
Bien sûr, qui est juste un rapide aperçu de la façon dont un système pourrait fonctionner, comment la bibliothèque de rubis fait.
Vous trouverez ici un tutoriel tout sur l'authentification reposant. http://railsforum.com/viewtopic.php?id=14216&p=13