#<UserSession: {:unauthorized_record=><protected>>>> [英] #<UserSession: {:unauthorized_record=>"<protected>"}>

查看:58
本文介绍了#<UserSession: {:unauthorized_record=><protected>>>>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 auth_logic 构建一个只需单击您的姓名即可登录"系统.我的用户模型有一个电子邮件和姓名字段.要登录,我只需:

I'm trying to build a "just click on your name to login" system using auth_logic. My user model has an email and name field. To login, I simply do:

UserSession.create(@user, true)

不幸的是,这不会导致创建会话.使用调试器我发现了这条消息:

Unfortunately that doesn't result in a session being created. Using a debugger I found this message:

#<UserSession: {:unauthorized_record=>"<protected>"}>

我的用户模型只有一行:

My user model just has one line:

acts_as_authentic

用户会话行有这个,我在某处找到的.我不确定它的作用,我试过有没有:

User session line has this, which I found somewhere. I'm not sure what it does and I've tried with and without:

class UserSession < Authlogic::Session::Base
  def to_key
     new_record? ? nil : [ self.send(self.class.primary_key) ]
  end
end

数据库(我也不确定是否需要 user_sessions 表):

The database (I'm also not sure if that user_sessions table is needed):

create_table "sessions", :force => true do |t|
  t.string   "session_id", :null => false
  t.text     "data"
  t.datetime "created_at"
  t.datetime "updated_at"
end

add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"

create_table "user_sessions", :force => true do |t|
  t.datetime "created_at"
  t.datetime "updated_at"
end

create_table "users", :force => true do |t|
  t.datetime "created_at"
  t.datetime "updated_at"
  t.string   "persistence_token"
  t.string   "email"
  t.string   "name"
end

我使用的是 Rails 3.0.9,我的 Gemfile 说(我尝试了普通和 Github authlogic gem):

I'm using Rails 3.0.9 and my Gemfile says (I tried both the normal and the Github authlogic gem):

gem 'rails', '3.0.9'
gem 'sqlite3'
gem "authlogic" #, :git => 'git://github.com/odorcicd/authlogic.git', :branch => 'rails3'

这里是其余的源代码.

几天前我在一个类似的项目中遇到了这个问题,它在某个时候消失了".我只是不记得是怎么做的.

I had this problem a few days ago on a similar project and it "just went away" at some point. I just don't remember how.

有什么想法吗?这让我发疯...

Any ideas? This is driving me nuts...

推荐答案

我最近遇到了这个问题,也很困惑.我已经找出了我的代码的具体问题,所以这是另一个潜在的解决方案.

I experienced this issue recently and was confused as well. I have figured out my code's specific problem so this is another potential solution.

我不明白 #<UserSession: {:unauthorized_record=>"<protected>"}> 仍然是有效的用户会话,只是我们自己创建的未经授权的会话.你可以通过调用 user 来确认这一点,你应该得到你传递给 UserSession.create 的任何 User 实例.

I did not understand that #<UserSession: {:unauthorized_record=>"<protected>"}> is still valid user session, just an unauthed one that we created ourselves. You can confirm this by calling user on it and you should get whatever User instance you passed into UserSession.create.

真正的问题有两个方面.current_user 方法的构建假设当前用户在请求的生命周期内不会改变并且我正在调用 current_user 在创建一个之前确保我没有一个.可以简化为:

The real issue is two fold. The current_user method was built with the assumption that the current user would not change during the lifetime of a request and I was calling current_user before creating one one to ensure I didn't have one already. It can be simplified to the following:

def current_user
  return @current_user if defined?(@current_user)

  @current_user = some_method_that_finds_a_proper_user
end

这里的关键是我寻找用户的方法可以返回nil.当它这样做时,它会将 @current_user 定义为 nil,因此缓存的值将始终在后续调用中返回.

The key here is that my method for finding a user can return nil. When it does, it will define @current_user as nil and thus that cached value will always be returned on subsequent calls.

这里有点困难,因为它实际上取决于您的代码需要什么.

Here's where it gets a bit harder as it really depends on what your code needs.

  1. 如果您在使用 UserSession.create 登录用户模型后不需要 current_user,那么您无需执行任何操作,只需等待渲染或重定向.在您的下一个请求中,您的 current_user 将被正确设置.

  1. If you do not need the current_user after signing a user model in with UserSession.create then you don't need to do anything but wait for the render or redirect. On your next request, your current_user will be properly set.

如果您不需要检查已登录的用户,请在 UserSession.create 之前删除对 current_user 的任何调用,如果可以,并且您第一次调用current_user 将按预期工作.

If you do not need to check for an already logged in user, remove any calls to current_user before UserSession.create if able and your first call to current_user will work as expected.

确保产生 current_user 的方法链不使用缓存,不缓存 nil,或者更改这些缓存值的保护以确定是否该值是真实的,而不是定义了实例变量.守卫可以改为:

Ensure your method chain that produces current_user either does not use caching, does not cache nils, or change the guard for these cached values to determine if the value is truthy instead of if the instance variable is defined. The guard could be changed to:

return @current_user if !@current_user.nil? # or @current_user.present? in Rails

或者您可以使用 Ruby 的 ||= 运算符和隐式返回.我上面的简化示例可以改为:

Or you can use Ruby's ||= operator and implicit return. My simplified example above could instead be:

def current_user
  @current_user ||= some_method_that_finds_a_proper_user
end

或者如果它不那么简单

def current_user
  @current_user ||= begin
    some_code
    doing_many
    things_here
  end
end

  • 或者您的问题可能是您在为此行为编写测试时遇到问题.在那种情况下,我宁愿只是对代码抱有期望

  • Or your problem could be that you're having trouble writing a test for this behavior. In that case I'd rather just put an expectation on the code like

    expect(UserSession).to receive(:create).with(user)
    

  • 这篇关于#&lt;UserSession: {:unauthorized_record=&gt;&lt;protected&gt;&gt;&gt;&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆