如何登录USER_NAME在Rails的?(How to log user_name in Rail

2019-06-24 22:59发布

我使用的设计用Rails 3.我希望看到production.log CURRENT_USER的名称。

我想配置这样的轨道:

config.log_tags = [:user_name]

Answer 1:

我发现这有点棘手,但工作的解决方案。

在会议监狱长存储用​​户信息,但req.session不可用于记录。

所以,你必须添加这的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)

然后创建文件的配置/初始化/ 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
]

现在我看到这个匿名:

[Anonym] Served asset ...

这对于用户:

[user_id:1] Served asset ...


Answer 2:

我使用WOJTEK Kruszewski此解决方案: https://gist.github.com/WojtekKruszewski

我调整了一点点我的项目只包括ID,但基本上是相同的。

# config/application.rb

config.log_tags = [
  ->(req){
    if user_id = WardenTaggedLogger.extract_user_id_from_request(req)
      user_id.to_s
    else
      "?"
    end
  }
]

而创造这个初始化

# initializers/warden_tagged_logger.rb

module 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


Answer 3:

新增2013年3月7日:

在Rails 4 encrypted_cookie_store是默认的会话存储。 这是如何访问会话数据:

session_data = req.cookie_jar.signed[ "_qnaire_session" ]

它看起来像warden_data看起来不同在我的新的应用程序,如: [[542], "$2a$10$e5aYxr/PIp6OOj8jzE7mke"] ,其中第一项是用户ID。

这是我目前的片断: https://gist.github.com/wojt-eu/5109643

上一版本:

这是我想出了:

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可以替换instance.config.session_options[:key]或经由单: Rails.application.config.session_options[:key]

我有ProviderUser模型,因此warden.user.provider_user.key 。 我与用户模型假定这将是warden.user.user.key

它的混乱,但如果有些更新仅标注日志将受到影响,这在注视开发日志,我应该很快注意到在打破它不影响正常验证处理,中间件堆栈顺序等。



Answer 4:

这是我刚才添加到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]}"
  }
]

这是Authlogic。 你需要做的可能会有所不同,所以你应该深入探讨,看看你的数据暴露给你了。

步骤1:

看什么req对象有可用。 这种添加到config/initializers/logging.rb

Rails.configuration.log_tags = [
  lambda { |req|
    req.inspect
  }
]

然后点击页面,看看被倾倒。

第2步:看看你的饼干罐有足够的信息,使用相同的技术:

Rails.configuration.log_tags = [
  lambda { |req|
    req.cookies.inspect
  }
]

(命中的请求)

顺便说一句:不要担心投入的用户名/电子邮件到日志 - 用户ID是不够好,你可以看看它在数据库中得到你所需要的任何额外的元数据。



Answer 5:

不幸的是日志标签在请求代表团一开始就只计算一次(在Rails::Rack::Logger中间件)。 在这个阶段,没有控制器,因此任何CURRENT_USER助手是尚未公布。 没有监狱长甚至会话建立呢,但有一个cookiejar至少,所以如果你保存你的session_id那里你可以恢复或日志的会话,而不是直接SESSION_ID。

config.log_tags = [ lambda { |req| req.cookie_jar["_session_id"].to_s } ]

我认为最好的办法是直接log_in在Cookie中保存的用户名,并与会话摧毁它。

config.log_tags = [ lambda { |req| req.cookie_jar["user_name"] || 'Noone' } ]

不工作:

但是,如果你使用的设计,它使用区长raack中间件,所以env['warden']应该是可用的,所以你可以尝试?

config.log_tags = [ lambda { |req| user = req.env['warden'].user; user && user.name || 'Noone'; } ]

即使没有监狱长,因为你通过有可用的会话env['rack.session']如果您存储用户ID的会话,你可以这样做

config.log_tags = [ lambda { |req| user = User.find_by_id(req.env['rack.session']['user_id']); user && user.name || 'Noone'; }


Answer 6:

几乎什么工作对我来说(Rails的3.2.22.2)是从这里的答案: http://benjit.com/rails/logger/2016/02/26/getting-admin-user-into-rails-logfile/

这假定cookie_jar到对象响应encrypted 。 但是它不适合我的情况。 最终什么工作对我来说是如下:

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}"
  }
]


Answer 7:

正如@viktortron在说他的回答在log_tags初始化的时候,我们还没有一个适当的session OBJET可用,但session_id是在请求。

如果您使用的是_database session_store_,因为它是我的话,你可以重建会议特设:

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

这是我如何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

  "%07d" % result
end

log_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

其结果是这样的:

[2013-01-22 13:51:36.659] [e52435d1] [0036484] <the log line>


Answer 8:

和现在完全不同的东西...

https://github.com/roidrage/lograge/issues/23#issuecomment-11709861

我只是试图与轨道4,最新的设计和Lograge。



Answer 9:

我使用Swards解决方案 ,它就像一个魅力。 然而,使用begin..rescue代替散列#对象的has_key? 是性能杀手

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

结果不言自明

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


Answer 10:

这里是饼干解密我的Rails 5.1使用标签功能与日志user_id ,存储在cookie中。 它基本上让我访问控制器相当于session[:user_id]从原始Cookie

环境/ 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
]

应用程序/模型/ 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


Answer 11:

作为一个快速和丑陋的解决方法,也许在请求被处理后,人们可以登录第二行。

这500 SERVERERROR已经被提出:#{用户名}



Answer 12:

对于使用Redis的::商店@ fjuillen的答案的人是这样的:

redis = Redis::Store.new
redis.select 3 # only if you use a different database
result = redis.get req.cookie_jar["_session_id"]

上轨道4进行测试。



文章来源: How to log user_name in Rails?