第二章登陆的实现html
金庸《倚天屠龙记》windows
张三丰缓缓摇头,说道:“少林派累积千年,方得达成这等绝技,决非一蹴而至,就算是绝顶聪明之人,也没法自创。”他顿了一顿,又道:“我当年在少林寺中住过,只是未蒙传授武功,直到此时,也不明白寻常血肉之躯如何能练到这般指力。”安全
前言服务器
你们确定不知道,要说其实 xmpp 里最关键、开发中也最很差解决的实际上是登陆过程你信么?网络
我要说我只用两句话就能完成 xmpp 登陆你信么?jsp
2.1 登陆的原理工具
前面的第一章写得稍显啰嗦,下面咱们来实现具体的功能。首先要实现的就是咱们这一节要说的登陆功能。学习
说来你们也许不相信,其实 xmpp 实现中最难的部分其实就是第一步:登陆。过了这一关以后,其实后面的部分几乎没有什么难度可言,就是些正常的客户机/服务器应答而已。测试
登陆部分难就难在其协议的复杂性和兼容性上。和电子邮件同样,其实登陆过程是有多种实现可选择的,不过这实际上并无什么必要所有实现(对于我的开发者来讲也不太可能有精力所有实现),就象电子邮件客户端同样,咱们实现其中一种最多见的就能够了,咱们在文章中会解释为什么选择这种登陆方式。ui
xmpp 和咱们前面介绍的 smtp/pop3 同样是以字符串应答为基础的,因此也能够将其交互过程以对话的形式进行描述(固然会有不同的地方,用到时咱们会提到)。具体的与服务器的对话方法咱们在《一步一步从原理跟我学邮件收取及发送》中已经介绍过了,不清楚的同窗能够移步过去先学习一下,这里咱们就不赘述了。
2.2 创建测试环境
和电子邮件同样,要测试咱们的程序和想法须要有一台可用的服务器,你们能够直接注册咱们的 newbt.net 免费邮箱,会自带 xmpp 功能。xmpp 的完整功能须要您升级为 1 元包年用户,不过咱们目前提到的功能在免费用户级别就能够完成了(其实咱们的 newbt 免费邮箱和 xmppmini 项目大致上是个众筹项目,你们以为有用就支持吧,不会强制收费)。但愿本身掌握服务器的同窗也可使用 openfire 服务器搭建,理论上也可使用 ejabberd ,不过在开发中笔者发现 ejabberd 的兼容性要比 openfire 差不少,因此推荐 openfire 。不过对于未来想本身开发服务器的同窗不推荐大家在 openfire 上二次开发,缘由咱们后面会讲到(文中若有提到ejabberd 则为ejabberd-19.08-windows)。
咱们 xmppmini 项目的帐号直接在 http://www.newbt.net:8888 上注册便可(希望您看到这篇文章的时候咱们项目还健在)。Openfire 须要在http://www.igniterealtime.org/projects/openfire/index.jsp 下载,笔者测试的版本是openfire-4.1.4-1 由于igniterealtime 家的向前兼容性并不怎么好,因此不能保证与最新版本的 openfire 兼容。Openfire 彷佛不支持多域名,因此在安装时若是是在局域网中测试,必定要先固定本身的 ip 不然下次开机后就可能没法链接了。
2.3 登陆协议与必需要注意的坑
如前所述咱们只介绍其中一种最经常使用的登陆协议,缘由为其余的登陆方式咱们得说上一周并且并不怎么实用。综合考虑推荐你们都使用这种登陆方式。在 xmpp 协议中,这种登陆方式称之为“PLAIN”。
一般 xmpp 链接的是服务器的 5222 端口,双方对话过程以下:
1. 客户端首先发送信息。
相似于:
<?xml version="1.0"?> <stream:stream xmlns:stream="http://etherx.jabber.org/streams" version="1.0" xmlns="jabber:client" to="newbt.net" xml:lang="en" xmlns:xml="http://www.w3.org/XML/1998/namespace">
服务器的回复相似于:
<?xml version='1.0'?> <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' from='xumatomacbook-pro.local' id='675c6847-c13d-4710-9844-d9339e4df087' version='1.0' xml:lang='en'>
就是这么简单的第一句对话,其中也有很容易出错的兼容性问题。
对于 openfire 和 newbt.net 服务器,to 的部分能够随便写。对于 ejabberd-19.08-windows 则必定要写上正确的对应域名(局域网测试的话则是 IP)
不然会报
<stream:error> <host-unknown xmlns='urn:ietf:params:xml:ns:xmpp-streams'/> </stream:error> </stream:stream>
另外,如今 ejabberd 的版本彷佛必定要 ssl 链接
可修改 C:/ProgramData/ejabberd/conf/ejabberd.yml 中的 starttls_required 为 false 不然无法用明文对话进行测试。
能够看到 xmpp 中收发的字符串并非标准的完整 xml 格式,其实严格来讲它只是 xml 格式的节点片断。其中的<?xml version='1.0'?> 并非必须的。了解这些在解码 xmpp 的信息时是很是重要的。
2.服务器回应,而且告知本身的可用登陆方式。
这第一句话的事情还没完,实际上真实的服务器并不会只回应一条语句,而是会再发送一条语句说明本身支持的功能。相似于:
<stream:features><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>PLAIN</mechanism></mechanisms></stream:features>
因此客户端发送第一条命令后要有准备,本身要接收两条回应信息,若是加上 xml 的信息头就有多是要接收三条回应,这和 smtp/pop3/ftp 这样的传统网络协议是不一样的。
3. 客户端选择最简单的 plaint 方式发送相应的用户名和密码。
相似于:
<auth mechanism="PLAIN" xmlns="urn:ietf:params:xml:ns:xmpp-sasl">AGNjY0BuZXdidC5uZXQAYWFhYWFh</auth>
这里有个问题。就是如今对网络拦截很是重视,理论上有可能会被拦截偷窥到密码。解决的办法 xmpp 给出了不少,不用那么麻烦,咱们选择最简单的,直接链接 5223 端口就能够了,除了使用的是 ssl/tls 的通信方式外其余的不用做任何更改。
发送的消息格式中,红色之外的部分是固定的,而红色部分是一个 base64 后的字符串,它的原文为:”\0用户名\0密码” 伪码以下:
Base64Encode("" + '\0' + user + '\0' + pass)
这里有个超级大坑,在标准协议中这里其实应该是 “登陆id+字符0+用户名+字符0+密码”,遗憾的是对这部分协议的理解各家有各家的见解(这种理解上的歧义在 smtp/pop3 中也是很是常见的,也是形成网络协议实现间不兼容的主要缘由之一)。目前兼容比较好的方式是将“登陆id”直接设置为空字符串,另外在“用户名”这里实际上要带上它的域名,即“用户名+@+host”,例如“clq@newbt.net”而不是直接写上 “clq”。关于这个问题我仔细对比过不少篇同行们的文章教程(rfc文档更不用说了),大多数做者都没有解释这部份内容,但最后他们的给出的代码中格式大多都是采用留空登陆 id 的方式。也欢迎你们回复探讨这一问题,特别是对 ejabberd 比较熟悉的用户。目前的现状是若是写了登陆 id 的话极可能是过不了 ejabberd 的登陆校验的。
4.服务器回应是否成功
相似于:
<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>
若是登陆失败的话则相似于:
<failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized></not-authorized></failure>
5.客户端接收响应,解析出是否成功。
客户端只要判断回应的消息中包含的是success 仍是failure 就能够了,连 xml 解码都用不着。
因此综上所述,其实最简单的 xmpp 登陆其实客户端只要发送两句话就能够了,并且换用安全套接字后就能够成为实用的登陆方式。
这其中的技术难点其实只有一个,那就是服务器回应消息的解码,在下一章节中咱们会介绍不使用第三方库的简单又实用的方式。
----------------------------------------------------------------
从本文中你们能够看出,本系列文章假定你们已经看过《一步一步从原理跟我学邮件收取及发送》系列文章,对于一些通用的操做一笔带过了(象base64的编码过程、如何用telnet等工具发送网络命令行、ssl/tls这些)。也节省了很多篇幅。不过这对于初学者有些不太公平,只有建议这部分读者先去认真的跟着《一步一步从原理跟我学邮件收取及发送》文章本身动动手先熟悉下网络程序的经常使用操做。
原文出处:https://www.cnblogs.com/-clq/p/12366844.html