如何在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对用户进行身份验证以将操作电缆用于个人消息
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 .
如果您首先在站点的某个位置(使用 devise_token_auth )进行通用的HTTP身份验证,那么您将获得3个身份验证标头-access_token
,client
,uid
.
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个auth标头:
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客户端):
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身份验证 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 < ApplicationCable::Channel
内部的任何位置访问current_user
!示例:
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
...