2016-03-20 7 views
3

В нашем приложении для нескольких арендаторов Rails 4.2 мы хотели бы определить поток локальный current_token для модели User и намереваться использовать его через все приложение. Вот как current_token определяется:Насколько безопасна нить локальная в Rails?

class User < ActiveRecord::Base 
    def self.current_token=(token) 
    Thread.current['current_token'] = token 
    end 

    def self.current_token 
    Thread.current['current_token'] 
    end 
end 

Токен извлекается с помощью User.current_token. Жизненно важно сохранить поток User.current_token безопасным и живым на протяжении всего сеанса пользователя. Указывается, что локальный поток может быть очищен некоторым веб-сервером, таким как puma. Мы хотели бы получить обратную связь от сообщества о том, как звук является локальным потоком в реальном производстве. Какую проблему мы должны знать (и возможное решение, если она есть). Благодарю.

ответ

5

Thread.current сам по себе является надежным. Риск Thread.current заключается в том, что вы должны использовать его правильно, потому что он не сбрасывается автоматически в конце запроса. Некоторые примеры:

  • Представьте, что вы установите маркер в Thread.current в одном запросе и не установлены в другой знак в следующем (возможно, потому, что не были никаких маркеров в следующем запросе), то старый маркер будет по-прежнему быть доступным.

  • Или вы планируете аннулировать Thread.current в конце каждого запроса, чтобы каждый запрос начинался с пробела Thread.current. Случится ли, если запрос завершится с исключением, все равно будет аннулирован?

Это просто подвержено ошибкам работать с Thread.current напрямую, и есть риск воздействия данных от одного запроса (один пользователь) на более поздний запрос (пользователя) на том же сервере.

Возможно, вы захотите проверить RequestStore gem, который внутренне использует Thread.current, но искажает его с некоторыми уровнями безопасности.

+0

Перенос старого токена на thread.current - настоящая проблема. Если 'thread.current' очищается и перезагружается в' before_action' и очищается в 'after_action' в одном контроллере, устраняет ли он риск? – user938363

+0

В основном, но вам также нужно подумать о промежуточном программном обеспечении. Просто посмотрите, как обрабатывает [RequestStore gem] (https://github.com/steveklabnik/request_store/blob/master/lib/request_store/middleware.rb). – spickermann

+0

Создает ли камень RequestStore 2 проблемы в вашем сообщении? Просто хочу подтвердить. Я прочитал несколько сообщений о драгоценности OrderStore и не совсем понял, как использовать драгоценный камень. Большое спасибо. – user938363

1

Я никогда не слышал о проблеме с puma и местными жителями. Возможно, вы захотите использовать sentient_user gem, так как его поведение очень близко к тому, что вы описываете. Единственное отличие состоит в том, что вместо того, чтобы хранить маркер, вы держите вокруг всего пользователя.

Замечу, что этот шаблон является в основном глобальной переменной, поэтому он действует как неустановленный параметр для любого метода, который его использует. Но это может быть хорошо для аудита, так что он всегда доступен независимо от того, где вам это нужно.

+0

Спасибо за комментарии. – user938363

Смежные вопросы