为什么我无法在渠道中检索main.o
或如何检索main.o: main.cpp
recipe
$(objects): %.o: %.cpp functions.h
recipe
?
我该使用什么?
尝试在rubydoc.info
中描述的ActionCable频道中获取current_user
代码看起来像
current_user
运行它,我收到此错误:
current_user
如果我删除class MessageChannel < ApplicationCable::Channel
identified_by :current_user
def subscribed
stream_from 'message_' + find_current_user_privileges
end
def unsubscribed
# Any cleanup needed when channel is unsubscribed
end
protected
def find_current_user_privileges
if current_user.has_role? :admin
'admin'
else
'user_' + current_user.id
end
end
end
,我会
[NoMethodError - undefined method `identified_by' for MessageChannel:Class]
答案 0 :(得分:4)
如果您看到自己提供的文档,则会发现identified_by
不是Channel
实例的方法。这是Actioncable::Connection
的一种方法。
从Rails操作系列概述指南,这是Connection
类的外观:
#app/channels/application_cable/connection.rb
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user
end
private
def find_verified_user
if current_user = User.find_by(id: cookies.signed[:user_id])
current_user
else
reject_unauthorized_connection
end
end
end
end
如您所见,此处无法使用current_user
。相反,您必须在此处创建current_user
。
websocket服务器没有会话,但它可以读取与主应用程序相同的cookie。所以我想,你需要在认证后保存cookie。
答案 1 :(得分:2)
在self.current_user
中设置ApplicationCable::Connection
后,它在通道实例中变为可用。
因此,您可以像Sajan所写的那样设置身份验证,只需在current_user
MessageChannel
例如,这段代码对我有用
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :verified_user
def connect
self.verified_user = find_verified_user
end
private
def current_user
jwt = cookies.signed[:jwt]
return unless jwt
decoded = JwtDecodingService.new(jwt).decrypt!
@current_user ||= User.find(decoded['sub']['user_id'])
end
def find_verified_user
current_user || reject_unauthorized_connection
end
end
end
class NextFeaturedPlaylistChannel < ApplicationCable::Channel
def subscribed
stream_from "next_featured_playlist_#{verified_user.id}"
end
end
答案 2 :(得分:1)
如果您在rails中使用devise gem,请替换此功能:
def find_verified_user # this checks whether a user is authenticated with devise
if verified_user = env['warden'].user
verified_user
else
reject_unauthorized_connection
end
end
我希望这对您有帮助。
答案 3 :(得分:1)
对于Rails 5 API模式:
application_controller.rb
class ApplicationController < ActionController::API
include ActionController::Cookies
...
token = request.headers["Authorization"].to_s
user = User.find_by(authentication_token: token)
cookies.signed[:user_id] = user.try(:id)
connection.rb
class Connection < ActionCable::Connection::Base
include ActionController::Cookies
...
if cookies.signed[:user_id] && current_user = User.where(id: cookies.signed[:user_id]).last
current_user
else
reject_unauthorized_connection
end
config / application.rb
config.middleware.use ActionDispatch::Cookies
答案 4 :(得分:0)
从理论上讲:
ActiveCable::Connection
类中的cookie。cookies.signed
和cookies.encrypted
因此,如果您知道会话cookie的名称(某种程度上很明显,将其称为“ _session
”),则可以通过以下方式简单地接收其中的数据:
cookies.encrypted['_session']
因此,您应该可以执行以下操作:
user_id = cookies.encrypted['_session']['user_id']
这取决于您是否在会话中使用cookie存储以及确切的身份验证方法,但是在任何情况下,所需的数据都应该存在。
我发现这种方法更方便,因为会话已经由您使用的身份验证解决方案进行管理,并且您很可能不必担心Cookie过期和身份验证逻辑重复之类的事情。
以下是更完整的示例:
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
session = cookies.encrypted['_session']
user_id = session['user_id'] if session.present?
self.current_user = (user_id.present? && User.find_by(id: user_id))
reject_unauthorized_connection unless current_user
end
end
end