ActionCable 中怎样使用 devise 进行验证
ActionCable是在rails中提供实时沟通的一个功能,与Laravel中的Broadcast功能类似。Devise则是一个非常著名的用于登录认证等内容的Gem。由于在ActionCable处理的过程中无法读取session的内容,但是能读取cookie的内容。所以本文介绍一下如何在ActionCable中处理devise的认证。
基本设置
# 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
这是在Rails的官方文档中为我们提供的基本配置,但是由于devise在处理登录的时候并没有为我们存储对应的cookie。那么我们应该怎么办呢?
设置Hook
我们可以通过设置Hook来让用户登录之后自动为我们设置cookie,具体如下
# app/config/initializers/warden_hooks.rb
Warden::Manager.after_set_user do |user,auth,opts|
scope = opts[:scope]
auth.cookies.signed["#{scope}.id"] = user.id
end
同时app/channels/application_cable/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
logger.add_tags 'ActionCable', current_user.name
end
protected
def find_verified_user
if verified_user = User.find_by(id: cookies.signed['user.id'])
verified_user
else
reject_unauthorized_connection
end
end
end
end
这样我们就可以完成基础认证啦!
另一种方法
经过一些搜索,我发现了可以使用另一种方法来实现认证,同时也不需要设置hook:
# 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
logger.add_tags 'ActionCable', current_user.name
end
protected
def find_verified_user
if verified_user = env['warden'].user
verified_user
else
reject_unauthorized_connection
end
end
end
end
不过,由于我对env['warden'].user
不太熟悉,就先不用这种方法啦?。
参考资料
本作品采用《CC 协议》,转载必须注明作者和本文链接