处理websocket连接的身份验证/授权的常用方法是使用在初始http升级请求时发送的cookie。这显示在http://edgeguides.rubyonrails.org/action_cable_overview.html
但是,如果我不想使用cookie,而是使用令牌呢?这里讨论了几个黑客Send auth_token for authentication to ActionCable,但它太过于hacky imo。
如果我将令牌授权逻辑移动到channel:
,该怎么办?module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :connection_id
def connect
self.connection_id = SecureRandom.hex # accept anyone, identify by random string
end
end
end
这将接受任何连接。而不是:
class TestChannel < ApplicationCable::Channel
def subscribed
if authorize(params[:token]) # check the token here
stream_from "test:1"
else
connection.close # alternatively `reject_subscription` to keep ws connection open
end
end
def unsubscribed
stop_all_streams
end
end
前端订阅将如下所示
App.test = App.cable.subscriptions.create(channel: "TestChannel", token: "hello-world")
这似乎有效。单个连接由随机字符串标识,每个通道订阅保持此唯一连接。当向该频道广播时,它将通过其唯一连接将数据推送给所有订户。因此,如果我们在这里拒绝订阅者,它将无法收到任何内容。但我们无法在订阅尝试之前关闭未经授权的连接。我可以打开与/ cable的连接并按照我的要求保持它。
但这样安全吗?这里显而易见的问题是,任何人都可以打开尽可能多的ws连接。这是这种方法的唯一问题吗?