【问题标题】:Receiving An unauthorized connection attempt was rejected w/ActionCable checking for Null Users接收 未经授权的连接尝试被拒绝,使用 ActionCable 检查 Null 用户
【发布时间】:2018-02-27 05:24:34
【问题描述】:

我正在尝试阻止 ActionCable 持续检查未登录到服务器的用户。我删除了测试环境中的所有用户以检查此问题是否会持续存在,但即使在我向 JS 文件添加条件语句以检查 current_user 的 id 之后,它也没有显示结束的迹象。我怎样才能最终结束 ActionCable 尝试连接不存在或未登录的用户的行为?顺便说一句,我正在使用 JQuery3 和 Rails 5。

控制台日志

Started GET "/cable" for 127.0.0.1 at 2018-02-27 00:11:41 -0500
   (1.0ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2018-02-27 00:11:42 -0500
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
  User Load (2.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" IS NULL LIMIT $1  [["LIMIT", 1]]
An unauthorized connection attempt was rejected
Failed to upgrade to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
Finished "/cable/" [WebSocket] for 127.0.0.1 at 2018-02-27 00:11:42 -0500
Finished "/cable/" [WebSocket] for 127.0.0.1 at 2018-02-27 00:11:42 -0500
Started GET "/cable" for 127.0.0.1 at 2018-02-27 00:12:09 -0500

连接.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.username
    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

cable.js

// Action Cable provides the framework to deal with WebSockets in Rails.
// You can generate new channels where WebSocket features live using the `rails generate channel` command.
//
//= require action_cable
//= require_self
//= require_tree ./channels

(function() {
  this.App || (this.App = {});

  App.cable = ActionCable.createConsumer();

}).call(this);

chatroom.js

$(document).on('turbolinks:load', function () {
    if ($("meta[name='current-user']").length > 0) {
        (function () {
            App.chatrooms = App.cable.subscriptions.create("ChatroomsChannel", {
                connected: function () {
                },
                disconnected: function () {
                },
                received: function (data) {
                    var active_chatroom;
                    active_chatroom = $("[data-behavior='messages'][data-chatroom-id='" + data.chatroom_id + "']");
                    if (active_chatroom.length > 0) {
                        if (document.hidden) {
                            if ($(".strike").length === 0) {
                                active_chatroom.append("<div class='strike'><span>Unread Messages</span></div>");
                            }
                            if (Notification.permission === "granted") {
                                new Notification(data.username, {
                                    body: data.body
                                });
                            }
                        } else {
                            App.last_read.update(data.chatroom_id);
                        }
                        return active_chatroom.append("<div class='media message'> <div class='media-body'> <h5 class='mt-0 message-username-pos'>" + data.username + "</h5> <p>" + data.body + "</p></div></div>");
                    } else {
                        return $("[data-behavior='chatroom-link'][data-chatroom-id='" + data.chatroom_id + "']").css("font-weight", "bold");
                    }
                },
                send_message: function (chatroom_id, message) {
                    return this.perform("send_message", {
                        chatroom_id: chatroom_id,
                        body: message
                    });
                }
            });

        }).call(this);
    }
});

last_read.js

$(document).on('turbolinks:load', function () {
    if ($("meta[name='current-user']").length > 0) {
        (function () {
            App.last_read = App.cable.subscriptions.create("LastReadChannel", {
                connected: function () {
                },
                disconnected: function () {
                },
                received: function (data) {
                },
                update: function (chatroom_id) {
                    return this.perform("update", {
                        chatroom_id: chatroom_id
                    });
                }
            });

        }).call(this);
    }
});

application.html.erb

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <title>Test App</title>
  <%= csrf_meta_tags %>

  <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  <%= javascript_include_tag 'https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js' %>
  <%= javascript_include_tag 'https://js.stripe.com/v3/' %>
  <%= favicon_link_tag 'favicon.ico' %>
  <% if user_signed_in? %>
      <%= tag :meta, name: 'current-user', data: {id: current_user.id} %>
  <% end %>
</head>

<body>
</body>
</html>

warden_hooks.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"] = 30.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

【问题讨论】:

    标签: javascript ruby-on-rails ruby actioncable


    【解决方案1】:

    我不确定我是否理解您的问题。然而连接是在这里发起的:

    (function() {
      this.App || (this.App = {});
    
      App.cable = ActionCable.createConsumer();
    
    }).call(this);
    

    因此,如果您不想连接,可以在此处添加检查。

    【讨论】:

    • 感谢您为我指明了正确的方向。我将发布解决方案,以供将来参考。
    【解决方案2】:

    要解决 ActionCable 不断 ping 的问题,您必须在 cable.js 中添加元数据检查器,如下所示

        $(document).on("turbolinks:load", function () {
        if ($("meta[name='current-user']").length > 0) {
            App.chatrooms = App.cable.subscriptions.create("ChatroomsChannel", {
                ...
            });
        } else if(App.chatrooms) {
           App.chatrooms.unsubscribe();
           delete App.chatrooms; 
        }
    });  
    

    【讨论】:

    • 只是想知道:我看到这个解决方案的一部分在你的 chatroom.js 文件中。您是否从该文件中删除了相关代码并将其放入 cable.js 中? ... 里面是什么?
    猜你喜欢
    • 2017-09-28
    • 2017-02-03
    • 1970-01-01
    • 2015-03-09
    • 1970-01-01
    • 1970-01-01
    • 2019-10-20
    • 2013-06-23
    • 1970-01-01
    相关资源
    最近更新 更多