ViT-Vetal-
ViT-Vetal-

Reputation: 2471

Is it possible use Doorkeeper with Action Cable?

I want use Doorkeeper authorization with Action Cable. Is it possible? Fot controllers I use before_action doorkeeper_authorize!

routes.rb

use_doorkeeper do
    skip_controllers :authorizations, :applications, :authorized_applications
end

mount ActionCable.server => '/cable'

UPDATE

Look like approach is same as here: http://www.rubydoc.info/github/rails/actioncable/ActionCable/Connection/Base

How To use devise_token_auth with ActionCable for authenticating user?

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 
        #CODE RELATED TO DOORKEEPER ????

        if user && user.valid_token?
          user
        else
          reject_unauthorized_connection
        end
      end
  end
end

Upvotes: 2

Views: 573

Answers (2)

Jai Kumar Rajput
Jai Kumar Rajput

Reputation: 4217

I am a bit late to answer this question but I have a cached answer for this!

Let me address the problem with @Vit-Vetal-'s answer:

This will allow action cable connection with expired Doorkeeper::AccessToken objects.

Here is the solution:

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

    def connect
      self.current_user = authenticate!
    end

    protected

    def authenticate!
      reject_unauthorized_connection unless doorkeeper_token&.acceptable?(@_doorkeeper_scopes)

      # this will still allow expired tokens
      # you will need to check if token is valid with something like
      # doorkeeper_token&.acceptable?(@_doorkeeper_scopes)

      user = User.find_by(id: doorkeeper_token.try(:resource_owner_id))

      user || reject_unauthorized_connection
    end

    def doorkeeper_token
      ::Doorkeeper.authenticate(request)
    end
  end
end

# ...

class SomeChannel < ApplicationCable::Channel
  def subscribed
     reject unless current_user
     stream_from 'some'
  end
end

Upvotes: 3

ViT-Vetal-
ViT-Vetal-

Reputation: 2471

UPDATED ANSWER

Developers added this example

OLD ANSWER

Result something like it:

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 
        user = User.find_by(id: access_token.resource_owner_id) if access_token 

        if user 
          user
        else
          reject_unauthorized_connection
        end
      end

      def access_token
        params = request.query_parameters()

        @access_token ||= Doorkeeper::AccessToken.by_token(params[:access_token])
      end
  end
end

or

class CarsLocationsChannel < ApplicationCable::Channel
  def subscribed
     reject unless current_user
     stream_from "cars_locations"
  end
end

Upvotes: 2

Related Questions