I am working on ActionCable
and implemented Doorkeeper
Authorization in my rails application.
I want to implement authenticate
my client with Doorkeeper::AccessToken
with ActionCable
Here is how I authenticated right now:
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
identified_by :room_id
def connect
self.current_user = find_verified_user
self.room_id = @user.ac_channel_room
end
def disconnect
# When user will disconnect action cable, this method call will be executed.
end
private
def find_verified_user
check_access_token
@user = User.find_by_id(@resource_owner_id) if @resource_owner_id
reject_unauthorized_connection unless @user
end
def check_access_token
# Check provided token is valid or not
params = request.query_parameters
@access_token ||= Doorkeeper::AccessToken.by_token(params[:access_token])
@resource_owner_id = @access_token&.resource_owner_id
end
end
end
Problem is this is allowing experied access tokens as well.
Please help!
Your question 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