Автоматический вход с Rails? - PullRequest
4 голосов
/ 17 ноября 2009

Я пытаюсь установить простую систему аутентификации с плагином Rails Restful-Authentication, и мне просто интересно, как он работает, потому что я не могу понять, каковы требования к файлам cookie и как сделайте так, чтобы браузер всегда запомнил вас (на 6+ месяцев).

Несколько вопросов:

1) Как вы помните, что для ruby's restful_authentication? Кажется, я не могу найти хороший однострочник для решения этой проблемы ...

Если пользователь регистрируется и проверяет «Помни меня», как приложение rails получает сеанс / cookie, когда пользователь ничего не делает, кроме перехода на страницу при следующем посещении страницы, скажем, через 3 месяца?

2) Нужно ли отправлять какую-либо информацию на сервер, например, их IP-адрес или что-то в этом роде? Что такое cookies[:auth_token], где это определено?

Цель: я не хочу, чтобы им снова приходилось вводить свой адрес электронной почты / пароль, например, как работает StackOverflow:)

Ответы [ 3 ]

7 голосов
/ 24 ноября 2009

Вот что мы делаем (в основном взяты из аутентифицированной системы) ... это метод контроллера, который обрабатывает вход в систему, который мы используем ...

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

И использовать это для выхода из системы

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

Тогда - в вашем application.rb вам понадобится что-то вроде:

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

И - в вашей модели User есть несколько методов, подобных этому:

# 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
0 голосов
/ 18 декабря 2009

Вы можете найти здесь целый учебник о спокойной аутентификации. http://railsforum.com/viewtopic.php?id=14216&p=13

0 голосов
/ 17 ноября 2009

Я, честно говоря, не уверен насчет этой конкретной реализации. Но распространенный метод аутентификации RESTful заключается в передаче хешированной версии пользователя / пароля с каждым запросом в качестве заголовка. В качестве альтернативы вы можете использовать хешированное значение cookie в качестве заголовка.

Я также видел гибридные системы, которые включают оба. Вы проходите в сеансе, если вы это знаете, в дополнение к пользователю / Pass. Затем на стороне сервера, если сеанс действителен, он использует его и может кэшировать сеанс -> отношение пользователя для производительности. Если сеанс недействителен, он пытается аутентифицироваться, используя user / pass.

В системе такого типа вы передаете сеанс обратно в ответе в качестве заголовка.

Конечно, это просто краткое изложение того, как может работать система, а не как работает библиотека ruby.

...