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不太熟悉,就先不用这种方法啦?。

参考资料

There's nothing wrong with having a little fun.

Epona
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!