gpt4 book ai didi

ruby-on-rails - Rails 应用程序中的代理 Websocket 请求

转载 作者:行者123 更新时间:2023-12-01 20:22:57 24 4
gpt4 key购买 nike

我有一个 Rails 应用程序和一个 Golang 服务。 Rails 应用程序是面向用户的带有 UI 的应用程序。来自前端的部分请求被路由到 golang 服务以实现某些功能。到目前为止,我们只有来自 UI 的 HTTP 请求。

现在我们在 UI 中有了 websockets 功能。所以我们需要通过 Rails Application 将这些 websocket 请求路由到 Golang 服务。基本上 Rails 应用程序控制身份验证/授权部分。所以我们需要通过 Rails 应用程序路由请求。

我们探索了 https://github.com/ncr/rack-proxy路由请求,但我们无法正确路由 websocket 请求。我们尝试了以下代码,其中在 ws://localhost:3000/ws/v1/stat 上接收到的网络套接字请求被发送到 ws://localhost:4000/ws/v1/stats 使用以下代码。

# frozen_string_literal: true
require 'rack-proxy'
module Proxy
ENV['SERVICE_URL'] ||= 'http://guides.rubyonrails.org'
class GoServiceProxy < Rack::Proxy
def perform_request(env)
request = Rack::Request.new(env)
# use rack proxy for anything hitting our host app at /example_service
# if request.path =~ %r{^/example_service}
if request.path =~ %r{stats}
backend = URI(ENV['SERVICE_URL'])
# most backends required host set properly, but rack-proxy doesn't set this for you automatically
# even when a backend host is passed in via the options
env["HTTP_HOST"] = 'localhost:4000'
# This is the only path that needs to be set currently on Rails 5 & greater
#env['PATH_INFO'] = ENV['SERVICE_PATH'] || '/configuring.html'
# don't send your sites cookies to target service, unless it is a trusted internal service that can parse all your cookies
env['HTTP_COOKIE'] = ''
super(env)
else
@app.call(env)
end
end
end
end

但是当我在 ws://localhost:3000/ws/v1/stat 上 curl 时,我收到 101 响应,但是从 go 服务发送的消息没有到来。以下屏幕截图是我得到的响应:

curl -v --request GET 'http://localhost:3000/ws/v1/stats' \
--header 'Content-Type: application/json' \
--header 'Upgrade: websocket' \
--header 'Connection: upgrade' \
--header 'Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==' \
--header 'Sec-Websocket-Version: 13'
Note: Unnecessary use of -X or --request, GET is already inferred.
* Trying ::1...
* TCP_NODELAY set
* Connection failed
* connect to ::1 port 3000 failed: Connection refused
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /ws/v1/stats HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Type: application/json
> Upgrade: websocket
> Connection: upgrade
> Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
> Sec-Websocket-Version: 13
>
< HTTP/1.1 101 Switching Protocols
< sec-websocket-accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
< Cache-Control: no-cache
< X-Request-Id: 957758f9-d762-43d0-bffb-fdd72efbfbc1
< X-Runtime: 0.002848
<
* Empty reply from server
* Connection #0 to host localhost left intact
curl: (52) Empty reply from server

有什么方法可以通过 Rails 应用程序代理 websocket 请求吗?

最佳答案

这听起来像是一个 A/B 问题。

您真正的问题是使用 Rails 凭证在 Go 应用程序上验证 WebSocket 用户。

为什么不代理连接

您的最新解决方案似乎是让 Rails 对用户进行身份验证,然后代理连接到 Go 应用程序。

此解决方案存在许多安全问题以及较大的性能损失。例如:

  1. (安全性)Go 应用程序假设所有连接都是“安全的”,通过让攻击者尝试直接连接到该服务或通过不同的路径(绕过 Rails 应用程序)使其成为网络攻击的便捷载体.

  2. (性能)所有网络流量和连接都增加了一倍(如果不超过一倍,实际上),给 Rails 应用程序带来更高的负载。

更好的解决方案

更好的解决方案是编写一个小型 Rails AUTH 应用程序,为 Go 应用程序提供身份验证服务。

Go 应用程序应该 执行身份验证。假设任何网络流量都是安全的(即使是看似本地的流量)也是灾难的根源。

这些身份验证服务可能会测试通过面向 Rails 用户的应用程序预先协商的长期身份验证 token (安全性差)或一次性身份验证 token (安全性更高)。

WebSocket 连接将直接连接到 Go 应用程序(很可能使用子域或 URL 路由)并使用身份验证微服务进行验证。

祝你好运!

关于ruby-on-rails - Rails 应用程序中的代理 Websocket 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61506081/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com