如何使用devise_token_auth和ActionCable来验证用户?

时间:2016-09-28 07:46:08

标签: ruby-on-rails authentication devise ruby-on-rails-5 actioncable

我有一个带有devise_token_auth gem身份验证的Rails 5 API。

现在我想要经过身份验证的用户进行个人聊天。我没有资产,因为我正在使用API​​,而且前端是本机应用程序,我想要本机应用程序消息传递。

所以我如何使用devise_token_auth gem验证用户使用动作电缆进行个人消息传递

2 个答案:

答案 0 :(得分:5)

此处ng-token-auth中Cookie中设置的auth_headers用于确定请求是否经过身份验证,否则连接被拒绝。

module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = find_verified_user
    end

    protected

      def find_verified_user # this checks whether a user is authenticated with devise_token_auth
        # parse cookies for values necessary for authentication
        auth_headers = JSON.parse(cookies['auth_headers'])

        uid_name          = DeviseTokenAuth.headers_names[:'uid']
        access_token_name = DeviseTokenAuth.headers_names[:'access-token']
        client_name       = DeviseTokenAuth.headers_names[:'client']

        uid        = auth_headers[uid_name]
        token      = auth_headers[access_token_name]
        client_id  = auth_headers[client_name]

        user = User.find_by_uid(uid)

        if user && user.valid_token?(token, client_id)
          user
        else
          reject_unauthorized_connection
        end
      end
  end
end

答案 1 :(得分:4)

Rails 5 API通常不支持任何cookie。请参阅:http://guides.rubyonrails.org/api_app.html#creating-a-new-application

如果您首先在您网站的某处(使用devise_token_auth gem)进行常见的HTTP身份验证,那么您将获得3个身份验证标头 - access_tokenclient,{{1} }。

在这种情况下,您可以使用这3个身份验证标头为您的Websockets连接使用基本身份验证(根据https://devcenter.heroku.com/articles/websocket-security#authentication-authorization):

致电(我使用Chrome Simple WebSocket Client):

uid

然后处理:

ws://localhost:3000/cable/?access-token=ZigtvvcKK7B7rsF_20bGHg&client=TccPxBrirWOO9k5fK4l_NA&uid=client1@example.com

这类似于常见的Websockets auth https://rubytutorial.io/actioncable-devise-authentication/

此类身份验证可能就足够了。我认为除了在频道订阅和发送到服务器的每个Websocket消息上进行身份验证之外,是必要的:

http://guides.rubyonrails.org/action_cable_overview.html#server-side-components-connections

  

对于服务器接受的每个WebSocket,都会实例化一个连接对象。此对象成为从上创建的所有通道订阅的父对象。除了身份验证和授权之外,连接本身不会处理任何特定的应用程序逻辑。

因此,如果您的关联是# Be sure to restart your server when you modify this file. Action Cable runs in an EventMachine loop that does not support auto reloading. module ApplicationCable class Connection < ActionCable::Connection::Base identified_by :current_user def connect params = request.query_parameters() access_token = params["access-token"] uid = params["uid"] client = params["client"] self.current_user = find_verified_user access_token, uid, client logger.add_tags 'ActionCable', current_user.email end protected def find_verified_user token, uid, client_id # this checks whether a user is authenticated with devise user = User.find_by email: uid # http://www.rubydoc.info/gems/devise_token_auth/0.1.38/DeviseTokenAuth%2FConcerns%2FUser:valid_token%3F if user && user.valid_token?(token, client_id) user else reject_unauthorized_connection end end end end ,那么您可以稍后在identified_by :current_user内的任何地方访问current_user!例如:

FooChannel < ApplicationCable::Channel

PS我想在Rails 5 API中使用cookies,你可以打开它:

http://guides.rubyonrails.org/api_app.html#other-middleware

<强>配置/ application.rb中

class AppearanceChannel < ApplicationCable::Channel
  def subscribed

    stream_from "appearance_channel"

    if current_user

      ActionCable.server.broadcast "appearance_channel", { user: current_user.id, online: :on }

      current_user.online = true

      current_user.save!

    end


  end

  def unsubscribed

    if current_user

      # Any cleanup needed when channel is unsubscribed
      ActionCable.server.broadcast "appearance_channel", { user: current_user.id, online: :off }

      current_user.online = false

      current_user.save!      

    end


  end 

end

http://guides.rubyonrails.org/api_app.html#adding-other-modules

<强>控制器/ API / application_controller.rb

config.middleware.use ActionDispatch::Cookies