2017-02-25 12 views
6

Dlaczego nie mogę odzyskać numeru current_user w swoim kanale lub w jaki sposób mogę pobrać current_user?Jak uzyskać current_user w aplikacji ActionCable rails-5-api?

Co używam?

  • Rails 5.0.1 --api (I nie mają żadnych widoków NOR użyciu kawy)
  • używam reagować-natywna aplikacja do testowania tego (działa dobrze bez zezwolenia)
  • nie używam opracować dla auth (używam JWT zamiast korzystania Knock, więc nie ma ciasteczka)

Próbuje current_user wewnątrz mojego ActionCable kanału w sposób opisany w rubydoc.info

Kod wygląda

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 

i uruchomienie go, otrzymuję ten błąd:

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

i gdybym usuń identified_by :current_user, otrzymuję

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

Odpowiedz

0

Dzięki @Sajan dla kickstarting mnie na właściwą drogę ...

Stworzyłem repo action-cable-react-jwt że właśnie robi dokładnie to, co prosiłem w pytaniu: szynach, reagują rodzimymi i JWT.

Ponieważ żądanie websocket tajemniczo nie pozwalają niestandardowe nagłówki do wysłania, ja po prostu nie brudne sztuczki aby uwierzytelnić JWTs (dołączając JWT w istniejącym nagłówku: D)

+0

jak to może być odpowiedź? albo mówi o brudnym haku, który bóg wie, co to jest, albo link repo? –

3

Jeśli zobaczysz dostarczony dokument, będziesz wiedzieć, że identified_by nie jest metodą dla instancji Channel. Jest to metoda dla Actioncable::Connection. Z prowadnicami dla Actioncable Przegląd, to jak klasa Connection wygląda następująco:

#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 

Jak widać, current_user nie jest dostępny tutaj. Zamiast tego musisz utworzyć tutaj połączenie w postaci current_user.

Serwer internetowy nie ma sesji, ale może odczytać te same pliki cookie, co główna aplikacja. Sądzę więc, że musisz zapisać cookie po uwierzytelnieniu.

+0

nie zbadali go dużo, ale na razie mogę wymyślić tylko jeden inny sposób, tj. wysłanie parametru zapytania, jak w przypadku używania domyślnego pliku cable.js dostarczanego przez szyny, użyj 'App.cable = ActionCable.createConsumer ('/ cable? token = 12345');' i użyj 'request.params [: token]' w klasie połączenia. Ale uważaj, nie wiem, czy wystawienie tokena jest bezpieczne. Dla mnie najlepiej jest podpisany plik cookie. Możesz ustawić go łatwo po zalogowaniu. – Sajan

+0

Tak, to jest niebezpieczne, aby odsłonić token w ten sposób:/Ale jest tak bardzo podobne do ciasteczka, tak jak gdyby ktoś dostał ciasteczko, może ukraść sesję, w ten sam sposób, jeśli ktoś dostanie ciąg JWT, może uwierzytelnia się z serwerem do momentu wygaśnięcia, tak jak plik cookie –

+0

gdzie jest "ciasteczka" _in 'cookies.signed [: user_id]' _ obj wyciągnięte z? Żądaj nagłówków? Jeśli tak, mogę wyciągnąć jwt w ten sam sposób ...! requestHeader ['Authorization'] dałoby to ... –

Powiązane problemy