web-dev-qa-db-fra.com

Comment obtenir current_user dans l'application ActionCable Rails-5-api?

Pourquoi ne puis-je pas récupérer current_user dans mon canal ou comment dois-je récupérer current_user?

Qu'est-ce que j'utilise?

  • Rails 5.0.1 --api(je n'ai aucune vue NOR utiliser café)} _
  • J'utilise react-native app pour tester ce(Fonctionne sans autorisation)
  • Je n'utilise PAS la carte pour l'auth(j'utilise plutôt JWT avec Knock, donc pas de cookies)

Essayer d’obtenir current_user dans mon canal ActionCable comme décrit dans rubydoc.info

Le code ressemble à

class MessageChannel < ApplicationCable::Channel
  identified_by :current_user

  def subscribed
    stream_from 'message_' + find_current_user_privileges
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end

  protected

  def find_current_user_privileges
    if current_user.has_role? :admin
      'admin'
    else
      'user_' + current_user.id
    end
  end

end

Et en l'exécutant, j'obtiens cette erreur:

[NoMethodError - undefined method `identified_by' for MessageChannel:Class]

Et si je supprime identified_by :current_user, je reçois

[NameError - undefined local variable or method `current_user' for #<MessageChannel:0x7ace398>]
11

Si vous voyez la documentation que vous avez fournie, vous saurez que identified_by n'est pas une méthode pour une instance Channel. C’est une méthode pour Actioncable::Connection. Du guide Rails pour Actioncable Overview, voici à quoi ressemble une classe Connection:

#app/channels/application_cable/connection.rb
module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = find_verified_user
    end

    private
      def find_verified_user
        if current_user = User.find_by(id: cookies.signed[:user_id])
          current_user
        else
          reject_unauthorized_connection
        end
      end
  end
end

Comme vous pouvez le constater, current_user n'est pas disponible ici. Au lieu de cela, vous devez créer un current_user ici en connexion.

Le serveur websocket n'a pas de session, mais il peut lire les mêmes cookies que l'application principale. Donc, je suppose que vous devez enregistrer les cookies après l'authentification.

4
Sajan

si vous utilisez des gemmes de carte dans Rails, veuillez remplacer cette fonction: 

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

J'espère que cela vous aidera.

0
Sochetra Nov