Sul*_*aig 3 authentication ruby-on-rails devise ruby-on-rails-5 actioncable
我有一个带有devise_token_auth gem身份验证的Rails 5 API .
现在我想要经过身份验证的用户进行个人聊天 我没有资产,因为我正在使用API,而前端是在本机应用程序中,我希望本机应用程序消息传递.
所以我如何使用devise_token_auth gem验证用户使用动作电缆进行个人消息传递
Rails 5 API 通常不支持 cookie。请参阅:http : //guides.rubyonrails.org/api_app.html#creating-a-new-application。
如果您首先在站点的某个地方(使用devise_token_auth gem)进行常见的 HTTP 身份验证,那么您将获得 3 个身份验证标头 - access_token, client, uid.
在这种情况下,您可以使用以下 3 个身份验证标头对 Websockets 连接使用基本身份验证(根据https://devcenter.heroku.com/articles/websocket-security#authentication-authorization):
调用(我使用Chrome Simple WebSocket Client):
ws://localhost:3000/cable/?access-token=ZigtvvcKK7B7rsF_20bGHg&client=TccPxBrirWOO9k5fK4l_NA&uid=client1@example.com
Run Code Online (Sandbox Code Playgroud)
然后处理:
# 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
Run Code Online (Sandbox Code Playgroud)
这类似于常见的 Websockets 身份验证https://rubytutorial.io/actioncable-devise-authentication/
这样的身份验证可能就足够了。我相信没有必要额外在频道订阅和发送到服务器的每个 Websocket 消息上进行身份验证:
http://guides.rubyonrails.org/action_cable_overview.html#server-side-components-connections
对于服务器接受的每个 WebSocket,都会实例化一个连接对象。此对象成为从那里创建的所有频道订阅的父对象。连接本身不处理身份验证和授权之外的任何特定应用程序逻辑。
因此,如果您的连接是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
Run Code Online (Sandbox Code Playgroud)
PS我你想在Rails 5 API中使用cookies,你可以打开它:
http://guides.rubyonrails.org/api_app.html#other-middleware
配置/应用程序.rb
config.middleware.use ActionDispatch::Cookies
Run Code Online (Sandbox Code Playgroud)
http://guides.rubyonrails.org/api_app.html#adding-other-modules
控制器/api/application_controller.rb
class Api::ApplicationController < ActionController::API
include ActionController::Cookies
...
Run Code Online (Sandbox Code Playgroud)
这里使用ng-token-authauth_headers在cookie中设置用于确定请求是否经过身份验证,如果不是,则拒绝连接.
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2083 次 |
| 最近记录: |