application 和 actioncable 不会共享 cookie
Posted
技术标签:
【中文标题】application 和 actioncable 不会共享 cookie【英文标题】:application and actioncable won't share cookie 【发布时间】:2016-03-30 22:33:42 【问题描述】:我正在使用设计进行身份验证,但是当我实施您的方法时,我得到“未经授权的连接尝试被拒绝”
经过几个小时的搜索,我发现:
cookies.signed['user.id']
返回零。在下面的代码块中。
def find_verified_user
if verified_user = User.find_by(id: cookies.signed['user.id'])
verified_user
else
reject_unauthorized_connection
end
end
我检查了,肯定有一个 cookie,但它不包含 Devise 设置的 cookie 数据。
要检查是否真的设置了“user.id”,我在视图中提出它。例外情况,这会返回用户 ID
Signed in as @#cookies.signed[:username].
- raise(cookies.signed['user.id'].inspect)
%br/
%br/
#messages
%br/
%br/
= form_for :message, url: messages_path, remote: true, id: 'messages-form' do |f|
= f.label :body, 'Enter a message:'
%br/
= f.text_field :body
%br/
= f.submit 'Send message'
我的问题/问题:
好像 cookie 在 actioncable 服务器上不可用。 有没有办法将 Devise 设置的 cookie 共享给有线服务器?
https://github.com/stsc3000/actioncable-chat.git
【问题讨论】:
这是我用来创建 actioncable 的示例 可能想看看这个:rubytutorial.io/actioncable-devise-authentication @Kkulikovskis 感谢您的回复!但我已经试过了。我不确定为什么这对我不起作用。如前所述,似乎 cookie 在 actioncable 服务器上不可用。而它在应用程序的浏览器中可用。 【参考方案1】:检查连接到 Action Cable 服务器的客户端 javascript 文件。有些教程把它放在 'app/assets/javascripts/application_cable.coffee' 和其他的 'app/assets/javascripts/channels/index.coffee' 但看起来像这样:
#= require cable
@App =
App.cable = Cable.createConsumer("ws://cable.example.com:28080")
您需要 WebSocket 地址指向您的 Cable 服务器,并且该地址需要与您的应用程序的其余部分共享一个 cookie 命名空间。您很可能指向错误的地方,例如,如果您在本地处理此问题,则需要进行更改:
App.cable = Cable.createConsumer("ws://cable.example.com:28080")
到
App.cable = Cable.createConsumer("ws://localhost:28080")
当然假设您的 Cable 服务器在端口 28080 上运行(在 bin/cable 可执行文件中指定)。 还要确保清除浏览器缓存,以便更新的文件是浏览器正在使用的文件。
【讨论】:
【参考方案2】:不确定您现在是否可以运行它,但我在 Rails 5.0.0.beta3 上遇到了同样的问题。我没有更改为以下行:
App.cable = Cable.createConsumer("ws://localhost:3000")
我保持原来的样子
@App ||=
App.cable = ActionCable.createConsumer()
但我所做的更改与 Cookie 有关。 无论如何。我的 user_id 的 cookie 不会显示。所以我做了一个工作。我得到了 cookie 来保存用户名,然后我终于能够在 find_verified_user 函数调用中看到它。
用户登录后(Sessions#create),我调用了一个辅助函数:
sessions_helper.rb
def set_cookie(user)
the_username = user.username.to_s
cookies.permanent.signed[:username] = the_username
end
新的 find_verified_user
def find_verified_user
if current_user = User.find_by_username(cookies.signed[:username])
current_user
else
reject_unauthorized_connection
end
end
这可能是也可能不是最好的解决方案,但经过数小时的困惑和挫折之后,这对我的情况有效。我希望这可以帮助某人
【讨论】:
您是否还想实现一种在退出时销毁 cookie 的方法? 是的,当您注销时只需销毁 cookie。【参考方案3】:我发现的问题是:我有2个不同的用户登录。一个在127.0.0.1登录,另一个在localhost登录。 所以当我使用 127.0.0.1:3000 访问我的网站时,但我的电缆配置为在 localhost 上运行,如下所示:
config.action_cable.url = "ws://localhost:3000/cable"
在 config/environments/development.rb 中
在 127.0.0.1 登录的用户向 "ws://localhost:3000/cable" 发出电缆请求(根据配置),但这样会发送为 localhost 保存的 cookie,即使我正在发出请求来自 127.0.0.1,这是不同的用户(或根本没有用户)。
所以底根其实就是上面Pwnrar所指的,有线地址配置和你访问网站的方式。
因此,要解决此问题,请始终使用为您的电缆配置的服务器地址访问您的网站,否则 cookie 会混入其中。
【讨论】:
【参考方案4】:需要在config/initializers/session_store.rb中配置
# using cookie store
if Rails.env.production?
# to share across subdomains
Rails.application.config.session_store :cookie_store,
key: '_app_name_session', domain: ".example.com"
else
# to share with any domain
Rails.application.config.session_store :cookie_store,
key: '_app_name_session', domain: :all, tld_length: 2
end
#for redis store
elsif Rails.env.production?
# to share across subdomains
Rails.application.config.session_store :redis_store,
servers: [
host: YourRedisHost, port: YourRedisPort,
],
key: '_app_name_session',
expire_after: 1.day,
domain: '.example.com'
else
# to share with any domain
Rails.application.config.session_store :redis_store,
servers: [
host: YourRedisHost, port: YourRedisPort,
],
key: '_app_name_session',
expire_after: 1.day,
domain: :all,
tld_length: 2
end
【讨论】:
以上是关于application 和 actioncable 不会共享 cookie的主要内容,如果未能解决你的问题,请参考以下文章
helper_method 不适用于 ActionCable
如何在 minitest 中模拟和验证 ActionCable 传输?