Rails Action Cable:如何授权传入连接?
Posted
技术标签:
【中文标题】Rails Action Cable:如何授权传入连接?【英文标题】:Rails Action Cable: How to authorize incoming connection? 【发布时间】:2018-10-07 18:43:17 【问题描述】:我正在尝试在 websocket 连接上实现授权(rails 5.2.1)
按照rubyonrails guideline,我创建了如下的connection.rb:
# 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 verified_user = User.find_by(id: cookies.encrypted[:user_id])
verified_user
else
reject_unauthorized_connection
end
end
end
end
很遗憾,所有的 websocket 连接请求都被拒绝了。 (我发现 cookies.encrypted[:user_id] 返回 nil。)
Started GET "/cable" for ::1 at 2018-10-07 21:33:46 +0300
Started GET "/cable/" [WebSocket] for ::1 at 2018-10-07 21:33:46 +0300
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."is_active" = $1 AND "users"."id" IS NULL LIMIT $2 [["is_active", true], ["LIMIT", 1]]
↳ app/channels/application_cable/connection.rb:12
An unauthorized connection attempt was rejected
Failed to upgrade to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
Finished "/cable/" [WebSocket] for ::1 at 2018-10-07 21:33:46 +0300
Finished "/cable/" [WebSocket] for ::1 at 2018-10-07 21:33:46 +0300
请指导我如何访问 app/channels/application_cable/connection.rb 中的当前用户信息?
【问题讨论】:
【参考方案1】:为了从 Devise 获取 current_user
,您需要更改您的 connection.rb
,如下所示:
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user
logger.add_tags 'ActionCable', current_user.email
end
protected
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
end
end
【讨论】:
我试过 cookies.signed 而不是加密,但没有任何改变。我还在“find_verified_user”方法上启用了调试器,似乎 cookies.signed[:user_id] 为零(尽管用户在 rails 中经过身份验证):(byebug) cookies.signed[:user_id] nil 顺便说一句,为了使用 Action Cable,我最近将这个应用程序从 Rails 4.2.10 升级到 Rails 5.2.1 。我只是想让你知道,因为这不是一个新的 rails 5.2.1 应用程序,我可能会遗漏一些可能需要的其他配置? 您是否使用devise
作为身份验证解决方案或任何其他用于此目的的gem?
我正在使用设计
那么我认为您需要更新您的connection.rb
文件,以便它与设计映射。例如。 if verified_user = env['warden'].user
在验证用户的情况下。查看以下链接,了解如何在使用 Devise 时设置 ActionCable:sitepoint.com/…【参考方案2】:
我遇到了确切的问题。我解决它的方法是在用户登录时添加一个cookie,通过SessionsController < Devise::SessionsController
。
代码如下所示:
class Users::SessionsController < Devise::SessionsController
# POST /resource/sign_in
def create
super
cookies[:user_id] = current_user.id
end
end
您可以通过运行代码从 devise 获取SessionsController
:
rails generate devise:controllers [scope]
在我的例子中,范围是用户。
【讨论】:
【参考方案3】:导轨 6:
cookies.encrypted[:user_id]
轨道 5:
cookies.signed[:user_id]
【讨论】:
以上是关于Rails Action Cable:如何授权传入连接?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Nginx、Puma 和 Redis 部署 Rails 5 Action Cable