Автоматический вход в Rails?
-
20-09-2019 - |
Вопрос
Я пытаюсь создать простую систему аутентификации с помощью плагина 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