用户身份的鉴别:
很多聊天室在传送数据包的时候,只是根据网页中隐含的字段得到用户的名称作为用户的标识来发送信息。比如国内比较典型的聊天站点(www.silversand.net)的用户的发送信息的数据包的格式是这样的:GET http://chat.silversand.net/BANNER?USER=username&
SAYS=%3Ch2%3Ethis+is+test%3C%2Fh2%3E&IMG=&IMGURL=&
WHOTO=%CB%F9%D3%D0%C8% CB&ACTION=%CB%B5%BB%B0&as=on&msg=HTTP/1.0 其中username就是表示该数据包是这个用户发送的。这样我们就很容易自己构建一个类似的数据包,而把用户名称替换成其他任何我们想要替换的人的名称,这样聊天室中的信息就会变得比较混乱,搞不清楚消息到底是谁发送的。
为了避免这个问题,我们的解决方案是这样的,当用户首次登入的时候,服务器系统应该生成一个唯一的sessionID来标识这个用户,这样,每次用户发送的数据包中必须包括这个sessionID,服务器根据这个sessionID来识别是否是该用户发送的消息,如果是一个不合法的sessionID的话,就简单的丢弃这个数据包。因为sessionID是在服务器端随机生成的,所以用户很难自己构造一个合法的sessionID来欺骗服务器,保证了信息来源的可靠性。当然如果服务器需要用户首先注册的话,可以同时检查用户的密码和sessionID是否匹配,这样用户伪造其他用户的信息的可能性就会更小。
关于用户发送重复的信息和自动循环发送随机信息(即通常所说的聊天室刷屏现象)的处理:
如果用户只是通过浏览器操作的话,服务器传送给用户的HTML文本中包含的Javascript就会在用户发送消息的时候比较用户的本次信息是否和上次信息相一致,如果是相一致的话,系统就不会发送本次信息并给出警告。而且如果用户是在浏览器上进行操作的话,用户的信息发送间隔会受到手工操作的限制。但是,如果用户是通过自己的应用程序发送数据包的话,就不会有这个限制。实际上用户可以在一个线程中不断对服务器循环发送数据包。所以系统不仅要考虑在客户端有这个限制,还需要在服务器端进行限制。
我们的解决方案是这样的,对所有在线的用户,我们建立了一个用户池,它实际上是一个用户对象的链表,每一个用户对象包含了用户的名称,用户的sessionID,用户的上一句发言的信息和用户上一句发言的时间。实际上这个用户池也是滚动的,如果用户在最近一段时间内没有任何信息,我们就认为该用户已经不在线上,就从信息池中删除该用户,以便为其他用户的连接让出资源。如果用户发送的消息和上一次消息相同的话,就简单的丢弃用户的这个数据包,如果用户这次消息的发送时间和上一次时间间隔小于一定范围(比如一秒)的话,我们就认为这种数据发送速率是非正常的,就简单的从用户池中删除这个用户,断掉这个连接。通过这种解决方法有效的解决了用户刷屏和发送重复消息的问题。
| 四 小结 |
本文介绍了Internet的聊天系统和不同的特点,重点介绍了聊天室存在的问题和一些攻击行为的防范,虽然黑客猖獗,不过胜利始终是属于正义一方的。