我目前正在使用html5 canvas和websockets构建一个带有游戏的网页。我有一个在服务器上运行的perl编写的websocket服务器:3000。在服务器上,我还安装了apache,并创建了一个用户可以访问的网站:http://server/。此页面上的javascript为ws:// server:3000
创建一个websocket连接正常,我可以从我的浏览器发送消息并获取响应,所有内容现在都显示在div中。我发送的消息现在只是“消息:...”,因此服务器知道它是一条消息,并向当前连接到“游戏”的所有用户输出“...”。
现在的问题是,任何人都可以编写自己的客户端,连接到ws:// server:3000并发送/接收相应的消息。这样他们就会使用我的后端,而不是我的客户端(我希望他们只能从http://server/播放)。
如何确保仅使用我的客户?主要担心的是作弊。您可以编写一个连接到端口的机器人,通过发送消息和解释它收到的消息为您播放...如何克服这个问题?
答案 0 :(得分:1)
我正在使用Jetty网络服务器。
我正在使用基本授权。我最初使用它只是因为它易于实现。但是,在发现websockets提供的授权问题后,我认为基本授权是一种很好的使用机制。
升级请求标头中包含授权数据:
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Authorization:Basic YWRtaW46cm9vdA==
Cache-Control:no-cache
Connection:Upgrade
在我的websocket服务器中,我调用了每个OnMessage事件:
session.getUpgradeRequest().getUserPrincipal()
然后,我可以使用此信息来决定是否授权处理数据。另外,我在OnConnect事件中检查套接字的来源:
session.getUpgradeRequest().getOrigin()
答案 1 :(得分:1)
你所要求的是不可能实现的。您可以采取措施使第三方难以制作未经授权的客户困难,但最终只要第三方能够使用您的合法客户,他们就可以随时观察它的作用并复制它,你无能为力阻止它。
但是你可以采取一些措施使其变得更难:
但即使你这样做,一个坚定的攻击者也可以解密和反混淆你的javascript,找到你用来加密消息的密钥,然后将它们恢复为纯文本并对他们的工作进行反向工程。
答案 2 :(得分:1)
基本身份验证有效,如此处的答案所示:HTTP headers in Websockets client API
使用基本身份验证,您可以在URL中包括用户名和密码:
ws://username:password@localhost:8888/
或者,您也可以通过协议,用户名或其他会话标识符发送哈希/ md5 / sha1密码来实现自己的安全性。 Of course it's good to have a token request before all that the client also passes up.
答案 3 :(得分:0)
网络的本质是这样的事情变得更容易(对于黑客)并且对于那些构建应用程序/网站更加困难。通常,您使用“referer”来确保请求来自您的站点/域。这不是万无一失的,但适用于大多数情况。
在Html 5中,我知道超链接不必发送引用者。这可能会改为包括websockets等。
即使您使用某种盐加密消息并将其散列与消息一起发送以根据服务器上的散列验证消息,您的客户端代码也可能是可用的,并且对任何人都可见他们可以破解你的逻辑。
WebSocket规范一直是不变的。有些浏览器暂时禁用或删除了他们的WebSocket支持。
WebSocket握手协议(使用Sec-WebSocket-Key1和Sec-WebSocket-Key2)应该会使事情变得有点安全,但是这个规范不适用于大多数代理服务器。你可以在这里阅读规范 http://www.whatwg.org/specs/web-socket-protocol/
请注意,握手协议是为了一个非常不同的目的而引入的。这不是你想要的,而是为了防止客户端攻击服务器,除非服务器通过握手响应,否则客户端无法与服务器通信。但在你的情况下,你需要在不知道客户的情况下通过握手做出回应。
所以我认为还没有一种可靠的方法可以满足您的需求。
答案 4 :(得分:0)
我遇到了同样的问题。我正在编写websocket->套接字代理,为我们的JAVA / Flash游戏制作HTML5客户端。他们在授权阶段使用自制加密来确保它是传统客户端。
我认为插入相同的加密代码并不安全,因为js文件的源是打开的。现在我在我的WS代理中隐藏了auth算法,但我现在需要以某种方式检测未授权的WS客户端:)
我正在使用网站上的临时会话ID来检查网站上是否授权了websocket客户端。虽然它不可靠。
此外,我正在考虑一些机制,让客户端(浏览器)下载动态生成的javascript文件,运行它,并发送到websocket服务器,可以检查有效的结果。这样我可以确定客户端是浏览器(或使用JS引擎的复杂机器人:))。无论如何,这只是我的想法,似乎很难实现,我还没有尝试过。
答案 5 :(得分:0)
非常简单我想,在websocket connect上添加一个标题,让它成为主机名或者其他东西,然后为它分配一些神秘的值,并在每次与webscoket服务器建立websocket连接时检查这个神秘的值。
答案 6 :(得分:0)
As others have remarked, you won't be able to enforce that only your own client-side code talks to your websocket. However, you can tie websocket connections to the rest of your web server.
For example, suppose you authenticate your players via a login form served by your web server. Then on successful login you generate a token that you hand out to the client, and have your client code pass the token as a query parameter that you can check against in your websocket connection handler:
http://server/play
(token, username, timestamp)
myGame.start(<literaltoken>)
ws://server:3000/?token=<token>
If you want to avoid having to keep state server-side, you could instead make the token an encrypted and signed blob of (username, timestamp)
, using some secret server-side key, and decrypt/verify that blob in the websocket handler.
答案 7 :(得分:-1)
以常规方式进行登录/身份验证,然后在Web套接字升级请求中包含会话ID。
答案 8 :(得分:-1)
我建议你看看其他服务是如何做到这一点的。 例如,请参阅pusher.com,特别是他们使用的私人频道 您可以在http://pusher.com/docs/pusher_protocol了解有关其协议的更多信息 您也可以查看其client libraries的源代码。