如何使用带有 ActionCable 的 devise_token_auth 来验证用户? [英] How To use devise_token_auth with ActionCable for authenticating user?

查看:21
本文介绍了如何使用带有 ActionCable 的 devise_token_auth 来验证用户?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有 devise_token_auth gem 身份验证的 Rails 5 API.

I have a Rails 5 API with devise_token_auth gem authentications.

现在我想与经过身份验证的用户进行个人聊天.我没有资产,因为我使用的是 API,前端是在本机应用程序中,我想要本机应用程序消息传递.

Now I want personal chat for authenticated users. I do not have assets as I am using API and front is in native apps and I want native apps messaging.

那么我如何使用 devise_token_auth gem 验证用户以使用 Action Cable 进行个人消息传递

So how I can authenticate users to use action cable for personal messaging using devise_token_auth gem

推荐答案

Rails 5 API 通常不支持 cookie.请参阅:http://guides.rubyonrails.org/api_app.html#creating-a-new-application .

No cookies are generally supported in Rails 5 API. See: http://guides.rubyonrails.org/api_app.html#creating-a-new-application .

如果您首先在您的站点的某个地方进行常见的 HTTP 身份验证(使用 devise_token_auth gem),然后你会得到 3 个身份验证标头 - access_tokenclientuid.

If you do a common HTTP-authentification at first somewhere at your site ( with devise_token_auth gem), then you get 3 auth headers - access_token, client, uid.

在这种情况下,您可以对 Websockets 连接使用基本身份验证(根据 https://devcenter.heroku.com/articles/websocket-security#authentication-authorization )使用这 3 个身份验证标头:

In such case you can use the Basic authentification for your Websockets connection (according https://devcenter.heroku.com/articles/websocket-security#authentication-authorization ) using these 3 auth headers:

调用(我使用 Chrome Simple WebSocket Client):

ws://localhost:3000/cable/?access-token=ZigtvvcKK7B7rsF_20bGHg&client=TccPxBrirWOO9k5fK4l_NA&uid=client1@example.com

然后处理:

# 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

这类似于常见的Websockets auth https://rubytutorial.io/actioncable-devise-authentication/

This is similar to the common Websockets auth https://rubytutorial.io/actioncable-devise-authentication/

这样的身份验证可能就足够了.我相信不需要另外在频道订阅和发送到服务器的每条 Websocket 消息上进行身份验证:

Such authentication is probably enough. I believe it is not necessary additionally to auth at the channel subscription and on every Websocket message sent to server:

http://guides.rubyonrails.org/action_cable_overview.html#服务器端组件连接

对于服务器接受的每个 WebSocket,都会实例化一个连接对象.这个对象成为从那里创建的所有频道订阅的父对象.连接本身不处理身份验证和授权之外的任何特定应用逻辑.

For every WebSocket accepted by the server, a connection object is instantiated. This object becomes the parent of all the channel subscriptions that are created from there on. The connection itself does not deal with any specific application logic beyond authentication and authorization.

因此,如果您的连接是 identified_by :current_user,那么您以后可以在 FooChannel FooChannel 中的任何位置访问 current_userApplicationCable::Channel!示例:

So if your connection is identified_by :current_user, you can later access current_user wherever inside your FooChannel < ApplicationCable::Channel! Example:

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 我想在 Rails 5 API 中使用 cookie,你可以打开它:

PS I you want to use cookies in Rails 5 API, you can switch it on:

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

config/application.rb

config.middleware.use ActionDispatch::Cookies

http://guides.rubyonrails.org/api_app.html#adding-其他模块

controllers/api/application_controller.rb

class Api::ApplicationController < ActionController::API

    include ActionController::Cookies
...

这篇关于如何使用带有 ActionCable 的 devise_token_auth 来验证用户?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆