Я помещу свой дюйм за 0,02$. Иногда Вы волнуете необходимость добавить "наконец" позже в Вашем коде (потому что, кто когда-нибудь пишет их коду отлично первый раз?). В тех случаях внезапно имеет больше смысла иметь попытку/выгоду вне цикла. Например:
try {
for(int i = 0; i < max; i++) {
String myString = ...;
float myNum = Float.parseFloat(myString);
dbConnection.update("MY_FLOATS","INDEX",i,"VALUE",myNum);
}
} catch (NumberFormatException ex) {
return null;
} finally {
dbConnection.release(); // Always release DB connection, even if transaction fails.
}
, поскольку, если Вы получаете ошибку, или нет, Вы только хотите выпустить свое соединение с базой данных (или выбрать Ваш любимый тип другого ресурса...) однажды.
Вы собираетесь пожертвовать некоторой безопасностью, делая это, но это определенно возможно. Есть два способа сделать это.
Первый - вы можете переопределить метод make_token в своей пользовательской модели. В настоящее время эта модель реализована следующим образом.
def make_token
secure_digest(Time.now, (1..10).map{ rand.to_s })
end
Каждый раз, когда пользователь входит в систему с или без cookie, вызывается метод make_token
, который генерирует и сохраняет новый Remember_token
для пользователь. Если у вас есть какое-то другое значение, уникальное для пользователя, которое невозможно угадать, вы можете заменить метод make_token
.
def make_token
secure_digest(self.some_secret_constant_value)
end
Это гарантирует, что токен никогда не изменится, но также позволит любому который получил токен, чтобы выдать себя за пользователя.
Кроме этого, если вы посмотрите на handle_remember_cookie!
в файле authenticated_system.rb
, вы сможете изменить этот метод, чтобы он работал на вас.
def handle_remember_cookie!(new_cookie_flag)
return unless @current_<%= file_name %>
case
when valid_remember_cookie? then @current_<%= file_name %>.refresh_token # keeping same expiry date
when new_cookie_flag then @current_<%= file_name %>.remember_me
else @current_<%= file_name %>.forget_me
end
send_remember_cookie!
end
Вы заметите, что этот метод вызывает три метода в модели пользователя, refresh_token
, Remember_me
и Forgot_me
.
def remember_me
remember_me_for 2.weeks
end
def remember_me_for(time)
remember_me_until time.from_now.utc
end
def remember_me_until(time)
self.remember_token_expires_at = time
self.remember_token = self.class.make_token
save(false)
end
#
# Deletes the server-side record of the authentication token. The
# client-side (browser cookie) and server-side (this remember_token) must
# always be deleted together.
#
def forget_me
self.remember_token_expires_at = nil
self.remember_token = nil
save(false)
end
# refresh token (keeping same expires_at) if it exists
def refresh_token
if remember_token?
self.remember_token = self.class.make_token
save(false)
end
end
Все три метода сбрасывают токен. Forgot_me
устанавливает его в nil
, тогда как два других устанавливают его в значение, возвращаемое make_token
. Вы можете переопределить эти методы в пользовательской модели, чтобы они не сбрасывали токен, если он существует и срок его действия не истек. Это, вероятно, лучший подход, или вы могли бы добавить дополнительную логику к методу handle_remember_cookie!
, хотя это, вероятно, было бы больше работы.
Если бы я был вами, Я бы переопределил Remember_me_until
, Forgot_me
и refresh_token
в пользовательской модели. Следующее должно работать.
def remember_me_until(time)
if remember_token?
# a token already exists and isn't expired, so don't bother resetting it
true
else
self.remember_token_expires_at = time
self.remember_token = self.class.make_token
save(false)
end
end
#
# Deletes the server-side record of the authentication token. The
# client-side (browser cookie) and server-side (this remember_token) must
# always be deleted together.
#
def forget_me
# another computer may be using the token, so don't throw it out
true
end
# refresh token (keeping same expires_at) if it exists
def refresh_token
if remember_token?
# don't change the token, so there is nothing to save
true
end
end
Обратите внимание, что, делая это, вы убираете функции, которые защищают вас от кражи токенов. Но это решение по рентабельности, которое вы можете принять.
You can change what the remember_token
is to achieve this. You can set it to:
self.remember_token = encrypt("#{email}--extrajunkcharsforencryption")
instead of
self.remember_token = encrypt("#{email}--#{remember_token_expires_at}")
Now there is nothing computer or time specific about the token and you can stay logged in from multiple machines.