Jak zalogować się do user_name w Railsach?


Używam Devise w Railsach 3. Chcę zobaczyć nazwę current_user w production.log.
Chciałbym ustawić szyny w ten sposób:
config.log_tags = [:user_name]

Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Uważam, że to trochę trudne, ale działające rozwiązanie.
Warden przechowuje informacje o użytkowniku w sesji, ale sesja req.session nie jest dostępna do rejestracji.
Musisz więc dodać to do config/application.rb
config.middleware.delete(ActionDispatch::Cookies)
config.middleware.delete(ActionDispatch::Session::CookieStore)
config.middleware.insert_before(Rails::Rack::Logger, ActionDispatch::Session::CookieStore)
config.middleware.insert_before(ActionDispatch::Session::CookieStore, ActionDispatch::Cookies)

Następnie utwórz plik config/initializers/logging.rb
Rails.configuration.log_tags = [
proc do |req|
if req.session["warden.user.user.key"].nil?
"Anonym"
else
"user_id:#{req.session["warden.user.user.key"][0][0]}"
end
end
]

Teraz widzę to dla anonimowego:
[Anonym] Served asset ...

a to jest dla użytkownika:
[user_id:1] Served asset ...
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Skorzystałem z takiego rozwiązania Wojtka Krushevsky'ego:

https://gist.github.com/WojtekKruszewski
https://gist.github.com/WojtekKruszewski
Poprawiłem trochę mój projekt, aby zawierał tylko identyfikator, ale w zasadzie to samo.
# config/application.rbconfig.log_tags = [
->(req){
if user_id = WardenTaggedLogger.extract_user_id_from_request(req)
user_id.to_s
else
"?"
end
}
]

I utwórz ten inicjator
# initializers/warden_tagged_logger.rbmodule WardenTaggedLogger
def self.extract_user_id_from_request(req)
session_key = Rails.application.config.session_options[:key]
session_data = req.cookie_jar.encrypted[session_key]
warden_data = session_data["warden.user.user.key"]
warden_data[0][0]
rescue
nil
end
end
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:


Dodane 07.03.2013:
>
W Railsach 4, encrypted_cookie_store jest domyślnym magazynem sesji. Oto jak możesz uzyskać dostęp do danych sesji:
session_data = req.cookie_jar.signed[ "_qnaire_session" ]

I wygląda na to, że warden_data wygląda inaczej w mojej nowej aplikacji, na przykład:
[[542], "$ 2a $ 10 $ e5aYxr/PIp6OOj8jzE7mke"]
, gdzie pierwszym elementem jest identyfikator użytkownika.
Oto mój aktualny fragment:

https://gist.github.com/wojt-eu/5109643
https://gist.github.com/wojt-eu/5109643

Poprzednia wersja:
>
Oto co wymyśliłem:
config.log_tags = [
:remote_ip,
->(req){
session_data = req.cookie_jar.signed[ "_qnaire_session" ]
warden_data = session_data["warden.user.provider_user.key"]
if warden_data
'#' + warden_data[1][0].to_s
else
"guest"
end
}
]

_qnaire_session
can be replaced with
instance.config.session_options[:key]
or via singleton:
Rails.application.config.session_options[:key]
Mam model ProviderUser, stąd
warden.user.provider_user.key
. Przypuszczam, że w przypadku modelu niestandardowego byłby to
warden.user.user.key
.
Jest brudny, ale nie wpływa na normalny proces uwierzytelniania, kolejność stosu oprogramowania pośredniego itp. Jeśli zepsuje się podczas jakiejś aktualizacji, wpłynie to tylko na dzienniki tagów, co powinienem szybko zauważyć, przeglądając dzienniki programowania.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Oto, co właśnie dodałem do
config/initializers/logging.rb
:
Rails.configuration.log_tags = [
:uuid, # request UUID
lambda { |req|
# Credentials are (currently) in the format of:
#
# <session_hash>::<user_id>
#
# So we have to split by '::' to obtain the user_id for logging.
#
# This will just output "User: nil" if there is no current session.
"User: #{req.cookies['user_credentials'].to_s.split('::')[1]}"
}
]

To jest dla Authlogic. To, co musisz zrobić, może się różnić, więc powinieneś naprawdę zagłębić się i zobaczyć, jakie dane już Ci zapewniają.
Krok 1:
Zobacz, co jest dostępne dla obiektu
req
. Dodaj
config/initializers/logging.rb
do tego:
Rails.configuration.log_tags = [
lambda { |req|
req.inspect
}
]

Następnie kliknij stronę i zobacz, co zostanie zresetowane.
Krok 2: Sprawdź, czy w Twoim słoiku z ciasteczkami jest wystarczająco dużo informacji, używając tej samej techniki:
Rails.configuration.log_tags = [
lambda { |req|
req.cookies.inspect
}
]

(kliknij na życzenie)
Nie martw się również wpisywaniem nazw użytkowników/e-maili w dziennikach - identyfikator użytkownika jest wystarczająco dobry i możesz go wyszukać w bazie danych, aby uzyskać dodatkowe potrzebne metadane.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Niestety, tagi dziennika są oceniane tylko raz na samym początku delegowania żądania (w oprogramowaniu pośrednim
Rails :: Rack :: Logger
). W tym momencie nie ma kontrolera, więc żaden pomocnik current_user nie jest jeszcze dostępny. Nie ma jeszcze nadzorcy, nawet sesji, ale przynajmniej jest cookiejar, więc jeśli zapiszesz tam swój session_id, możesz przywrócić sesję lub bezpośrednio wprowadzić session_id.
config.log_tags = [ lambda { |req| req.cookie_jar["_session_id"].to_s } ]

Myślę, że najlepszą alternatywą jest przechowywanie nazwy użytkownika w pliku cookie bezpośrednio w log_in i niszczenie go wraz z sesją.
config.log_tags = [ lambda { |req| req.cookie_jar["user_name"] || 'Noone' } ]

NIE DZIAŁA:
Ale jeśli używasz devise, używa on oprogramowania pośredniego warden raack, więc
env ['warden']
powinno być dostępne, więc czego możesz spróbować?
config.log_tags = [ lambda { |req| user = req.env['warden'].user; user && user.name || 'Noone'; } ]

Nawet bez naczelnika, ponieważ masz sesję dostępną przez
env ['rack.session']
, jeśli przechowujesz identyfikator użytkownika w sesji, możesz zrobić coś takiego
config.log_tags = [ lambda { |req| user = User.find_by_id(req.env['rack.session']['user_id']); user && user.name || 'Noone'; }
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

A teraz o czymś zupełnie innym ...
https://github.com/roidrage/lo ... 09861
https://github.com/roidrage/lo ... 09861
Właśnie tego spróbowałem z Rails 4, najnowszym wynalazkiem i Lograge.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

To, co prawie zadziałało dla mnie (Rails 3.2.22.2), to odpowiedź stąd:

http://benjit.com/rails/logger ... gfile
http://benjit.com/rails/logger ... file/
/
Zakłada się, że obiekt
cookie_jar
odpowiada na
encrypted
. Jednak w moim przypadku tak się nie stało. To, co ostatecznie zadziałało dla mnie, to:
config/initializers/logging.rb
:
Rails.configuration.log_tags = [
lambda { |req|
session_key = Rails.application.config.session_options[:key]
session_data = req.cookie_jar.signed[Rails.application.config.session_options[:key] ]
warden_data = ( session_data["warden.user.user.key"]|| [[]])
admin_user = warden_data[0][0]
"u: #{admin_user || 0}"
}
]
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Jak powiedział @viktortron w

Twoja odpowiedź
https://stackoverflow.com/a/10813097/316700
w momencie inicjalizacji
log_tags
nie mamy odpowiedniego obiektu
session
, ale w żądaniu znajduje się
session_id
.
Jeśli używasz _database session_store_, tak jak w moim przypadku, możesz przebudować

sesja

ad-hoc:
session = ActiveRecord::SessionStore::Session.find_by_session_id(request.cookie_jar["_session_id"])

Oto jak zdefiniowane są moje
log_tags
:
# config/initializers/rails_log.rb
def get_user_id(req)
session = ActiveRecord::SessionStore::Session.find_by_session_id(req.cookie_jar["_session_id"])
result = session ? session.data["user_id"] : 0 "d" % result
endlog_tags = []
log_tags << lambda { |req| Time.now.strftime("%F %T.%L") }
log_tags << lambda { |req| req.uuid.first(8) }
log_tags << lambda { |req| get_user_id(req) }Rails.configuration.log_tags = log_tags

Wynik jest taki:
[2013-01-22 13:51:36.659] [e52435d1] [0036484] <the log line>
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

używam

decyzja
https://stackoverflow.com/a/28117273/518204
Swards i działa jak zaklęcie. Jednak użycie
begin..rescue
zamiast Hash # has_key? Czy zabija wydajność
require 'benchmark/ips'good_hash = { 'warden.user.admin_user.key' => [[1]]}
bad_hash = {}Benchmark.ips do |x|
x.report('begin+rescue good hash') { good_hash['warden.user.admin_user.key'][0][0] }
x.report('has_key good hash') do
good_hash.has_key?('warden.user.admin_user.key') &&
good_hash['warden.user.admin_user.key'][0][0]
end x.report('begin+rescue bad hash') { bad_hash['warden.user.admin_user.key'][0][0] rescue nil }
x.report('has_key bad hash') do
if bad_hash.has_key?('warden.user.admin_user.key')
bad_hash['warden.user.admin_user.key'][0][0]
end
end # Compare the iterations per second of the various reports!
x.compare!
end

Wyniki mówią same za siebie
Comparison:
has_key bad hash: 4870164.1 i/s
begin+rescue good hash: 3544134.7 i/s - 1.37x slower
has_key good hash: 2127500.6 i/s - 2.29x slower
begin+rescue bad hash: 4468.2 i/s - 1089.95x slower
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Oto dekoder plików cookie, których używam w Railsach 5.1 do oznaczania dzienników
user_id
, który jest przechowywany w pliku cookie. To w zasadzie pozwala mi uzyskać dostęp do kontrolera odpowiadającego
session [: user_id]
z surowego pliku cookie
environments/production.rb:
config.log_tags = [
:request_id,
:remote_ip,
lambda do |req|
session_data = CookieDecrypter.new(req).session_data
"user_id:#{session_data['user_id']}"
end
]

app/models/cookie_decrypter.rb:
class CookieDecrypter
attr_reader :request def initialize(request)
@request = request
end def session_data
cookie = request.cookies[session_key]
return {} unless cookie.present?
cookie = CGI::unescape(cookie)
key_generator = ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000)
secret = key_generator.generate_key(salt)[0, ActiveSupport::MessageEncryptor.key_len]
sign_secret = key_generator.generate_key(signed_salt)
encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: JSON)
encryptor.decrypt_and_verify(cookie) || {}
end private def session_key
Rails.application.config.session_options[:key]
end def secret_key_base
Rails.application.secrets[:secret_key_base]
end def salt
Rails.application.config.action_dispatch.encrypted_cookie_salt
end def signed_salt
Rails.application.config.action_dispatch.encrypted_signed_cookie_salt
end
end
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

W ramach szybkiego i brzydkiego obejścia być może po przetworzeniu żądania można by napisać drugą linię.
Ten błąd 500 ServerError został przesłany przez: # {nazwa użytkownika}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Dla osób korzystających z Redis :: Store @ fjuillen's odpowiedź wygląda następująco:
redis = Redis::Store.new
redis.select 3 # only if you use a different database
result = redis.get req.cookie_jar["_session_id"]

testowany na szynach 4.

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się