Pergunta

Estou tentando criar um sistema de autenticação simples com o plug-in de autenticação de Rails e estou apenas me perguntando como funciona, porque não consigo descobrir quais são os requisitos para os cookies e como fazê-lo assim O navegador sempre se lembra de você (por mais de 6 meses).

Algumas perguntas:

1) Como você se lembra de_me para o RUBY's RESTful_authentication? Não consigo encontrar uma boa linha para resolver esse problema ...

Se um usuário se inscrever e verificar "Lembre -se de mim", como o aplicativo Rails recebe a sessão/cookie sem que o usuário faça nada além de ir para a página na próxima vez que eles vão para a página, digamos três meses depois?

2) Preciso enviar algum tipo de informação ao servidor, como o endereço IP do seu ou algo assim? O que é cookies[:auth_token], onde isso é definido?

O objetivo é: eu não quero que eles tenham que inserir o e -mail/senha novamente, como o StackOverflow funciona :)

Foi útil?

Solução

Aqui está o que estamos fazendo (amplamente retirado do sistema autenticado) ... Este é o método do controlador que lida com o login que estamos executando ...

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

E use isso para logout

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

Então - em seu aplicativo.rb você precisará de algo como:

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

E - no seu modelo de usuário tem alguns métodos como este:

# 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

Outras dicas

Sinceramente, não tenho certeza de que a implementação específica. Mas um método de autenticação comum é passar uma versão de hash do usuário/senha com cada solicitação como cabeçalho. Como alternativa, você pode usar um valor de cookie de hash como cabeçalho.

Eu também vi sistemas híbridos que envolvem ambos. Você passa na sessão, se souber, além do usuário/Pass. Em seguida, o lado do servidor, se a sessão for válido, usa isso e pode cache a sessão -> relacionamento do usuário para desempenho. Se a sessão for inválida, ela tenta autenticar usando o usuário/passagem.

Nesse tipo de sistema, você passaria a sessão de volta à resposta como cabeçalho.

É claro que esse é apenas um rápido resumo de como um sistema pode funcionar, não como a biblioteca da Ruby.

Você pode encontrar aqui um tutorial inteiro sobre autenticação RESTful.http://railsforum.com/viewtopic.php?id=14216&p=13

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top