3

레일 5 API에 devise_token_auth gem 인증이 있습니다.어떻게 사용자를 인증하기 위해 devise_token_auth를 ActionCable과 함께 사용 하시겠습니까?

이제 인증 된 사용자의 개인 채팅을 원합니다. 내가 API를 사용하면서 자산이 없으며 프론트가 네이티브 어플리케이션에 있고 네이티브 앱 메시징을 원합니다.

그래서 사용자가 아니라 연결이 거부되는 경우 요청, 인증 여부를 결정하는 데 사용되는 ng-token-auth하여 쿠키에 devise_token_auth 보석을 여기

답변

3

일반적으로 Rails 5 API에서 쿠키는 지원되지 않습니다. 참조 : http://guides.rubyonrails.org/api_app.html#creating-a-new-application. access_token, client, uid - 당신이 (devise_token_auth 보석과) 사이트에서 첫 번째 어딘가에서 일반적인 HTTP-위한 인증을 할 경우

는, 당신은 3 인증 헤더를 얻는다. 이러한 경우에

이러한 3 인증 헤더를 사용하여 (https://devcenter.heroku.com/articles/websocket-security#authentication-authorization 따라) 당신의 WebSocket을 연결 기본위한 인증을 사용할 수 있습니다

전화 (내가 Chrome Simple WebSocket Client 사용) :

ws://localhost:3000/cable/?access-token=ZigtvvcKK7B7rsF_20bGHg&client=TccPxBrirWOO9k5fK4l_NA&[email protected] 

그런 과정 :

# 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 

일반적인 웹 소켓 인증과 비슷합니다. https://rubytutorial.io/actioncable-devise-authentication/

이러한 인증으로 충분할 수 있습니다. 나는 그것이 채널 구독에서 서버로 전송 모든 웹 소켓 메시지에 정식에 추가로 필요한 하지이라고 생각 : 서버에 의해 허용 모든 웹 소켓의 경우

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

이 연결 객체가 인스턴스화됩니다. 이 객체 에 생성 된 모든 채널 구독의 부모가됩니다. 연결 자체는 인증 및 권한 부여 이상의 특정 응용 프로그램 논리를 처리하지 않습니다.

연결이 identified_by :current_user 경우 그래서, 당신이 할 수있는 나중에 액세스 current_user 어디서든 FooChannel < ApplicationCable::Channel 내부! 예 :

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 

PS 난 당신이 레일에서 5 API를 쿠키를 사용하려면, 당신은 그것을에 전환 할 수 있습니다

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

설정/응용 프로그램을.RB

config.middleware.use ActionDispatch::Cookies 

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

컨트롤러/API/application_controller.rb

class Api::ApplicationController < ActionController::API 

    include ActionController::Cookies 
... 
+0

어떻게합니까? 당신은 토큰을 cable.js 파일에 넣을까요? 'App.cable = ActionCable.createConsumer ('/ cable/'+ token);'사용자로부터 토큰을 얻는 방법을 알 수 없다. –

+0

cable.js가 없다. 이 파일은 Rails API 전용 케이스이므로 http://guides.rubyonrails.org/api_app.html에 있습니다. 문제는 여기에 설명되어 있습니다. https://stackoverflow.com/questions/13826594/coffeescript-access-to- 현재 사용자/43250865 # 43250865 – prograils

5

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

네이티브 응용 프로그램에서 토큰 인증,이 쿠키는 API 서버에서 설정해야 가정 해 봅시다입니다 ?? – tommyalvarez

+0

@tommyalvarez 위에서 볼 수있는 코드는 하이브리드 코덱 응용 프로그램에 연결되는 백엔드에서 온 것입니다. cordova 앱은 쿠키를 설정하는 ng-token-auth를 사용합니다. 네이티브 앱의 경우 각 요청의 헤더에 인증 데이터를 전송한다고 생각합니다. 그러나 여전히 흐름은 매우 유사 할 것입니다. – quintencls

+0

@quintencis, 문제는 웹 소켓에 대해 ws 프로토콜에 지정된 것 이외의 커스텀 헤더를 보낼 수 없다는 것인데, 당연히 uid, access-token 또는 client :(나는 토큰을 보내지 않았다. uid 및 클라이언트 URL에서 쿼리 문자열로 매우 불안정합니다. – tommyalvarez

관련 문제