Вопрос

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

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

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

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

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

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

Это было полезно?

Решение

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

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

И - в вашей модели пользователя есть такие методы:

# 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

Другие советы

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top