Rails Devise Action Cable

13

我正在尝试让Action Cable与Devise一起工作。

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
      verified_user = User.find_by(id: cookies.signed['user.id'])
      if verified_user && cookies.signed['user.expires_at'] > Time.now
        verified_user
      else
        reject_unauthorized_connection
      end
    end
  end
end
如果用户已登录,但我仍然从cookies.signed ['user.id']获取到nil

你是否还在想为什么官方文档告诉你要这样做,但对我来说却不起作用。 - Petercopter
2个回答

31

请在您的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.studentid
    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

链接: https://www.pluralsight.com/guides/implementing-a-custom-devise-sign-in-and-actioncable-rails-5


3
这应该使用哪个版本的Rails / Devise / Warden? env['warden'].user 总是为空。 - Arnold Roa
@ArnoldRoa 仅在您之前的某个地方执行过身份验证,即已使用经典设备表单登录时才包含该值。这将设置一个 cookie,之后,warden 的 rack 中间件将在每个请求上设置 env['warden'].user - Nikolay Shebanov
1
我遇到了类似的问题,我已经注销并重新登录尝试过了,但是env['warden'].user始终为空。 - opensource-developer

5
尝试在 Warden 回调中设置 cookie。
将文件添加到 `config/initializers/your_file.rb`。
在文件中添加以下内容:
Warden::Manager.after_set_user do |user, auth, opts|
  scope = opts[:scope]
  auth.cookies.signed["#{scope}.id"] = user.id
  auth.cookies.signed["#{scope}.expires_at"] = 60.minutes.from_now
end

Warden::Manager.before_logout do |user, auth, opts|
  scope = opts[:scope]
  auth.cookies.signed["#{scope}.id"] = nil
  auth.cookies.signed["#{scope}.expires_at"] = nil
end

或者你可以像这样做:

verified_user = env['warden'].user

正如这篇非常好的教程所解释的那样:使用Rails 5、ActionCable和Devise创建聊天应用程序。


2
这对我很有效,除了我的用户不是使用devise设置的默认用户。例如,如果您有不同类型的用户登录,只需将该用户类型作为下一个参数添加即可,如verified_user = env['warden'].user('admin_user') - Timbinous
3
正确的注销代码:Warden::Manager.before_logout do |user, auth, opts| scope = opts[:scope] auth.cookies.delete("#{scope}.id") auth.cookies.delete("#{scope}.expires_at") end - prograils
2
如果您正在使用Devise,请使用auth.cookies.signed["#{scope}.expires_at"] = Devise::timeout_in.from_now - Yakob Ubaidi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接