在XMPP開發中,使用XMPPStream進行連接服務器后,驗證過程中,比較常見的一個錯誤是
<failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure>.
尤其作為初學者(筆者就是這樣的),經常會因為這個問題弄得不着邊際的凌亂.現在筆者將自己的遇到的問題定期整理,總結錯誤,希望對日后的使用有所參考,同時希望能夠對也是在這方面的初學者有所提醒.
服務器的測試版本為openfire 3.9.3 ; 數據庫使用的是MYSQL; Mac環境為Xcode5.1.1;
開放中,一般在設置了XMPPStream的JID以及hostname之后,就可以進行連接服務器:
NSString *name = [[NSUserDefaults standardUserDefaults] objectForKey:@"name"]; NSString *host = [[NSUserDefaults standardUserDefaults] objectForKey:@"host"]; XMPPJID *myJID = [XMPPJID jidWithUser:name domain:host resource:nil]; _xmppStream.myJID = myJID; _xmppStream.hostPort = 5222; _xmppStream.hostName = host; NSError *error; if ([_xmppStream isConnected]) { [_xmppStream disconnect]; } [_xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error];
正常情況下,連接服務器成功(此時並不需要密碼嚴重)后,XMPPStream會通知代理,那么我們就可以在代理的相應方法中,進行連接后的操作:
1 - (void)xmppStreamDidConnect:(XMPPStream *)sender 2 { 3 NSLog(@"連接成功"); 4 NSString *passwd = [[NSUserDefaults standardUserDefaults] objectForKey:@"passwd"]; 5 NSError *error; 6 [_xmppStream authenticateWithPassword:passwd error:&error]; 7 8 9 }
一般在這里進行用戶的密碼驗證,雖然authenticateWithPassword:erroe:方法在官方的解釋里面說會在后續的版本中漸漸丟棄,但這無疑是我們用來測試驗證的非常方便的一個接口.
這時候,我們經常會在密碼正確的時候,遇到
<failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure>這個錯誤.
作為初學着遇到這個問題,常常覺得莫名其妙,明明密碼是正確的,但系統就是提示認證失敗,而且如果使用Spark這樣的客戶端,卻完全可以正常登錄服務器;最難過的是,在XMPPStream的這個錯誤中,沒有所謂的code碼,這就更難定位到底是哪里出了問題(不像用戶名和密碼的錯誤提示code8,以及服務器相關的code61那么友善).
這個錯誤會通過XMPPStream代理返回來:
1 - (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error 2 { 3 NSLog(@"%@",error); 4 }
// <failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure>
其實,XMPP認證的問題,一般都是與JID有關的,因此解決這類問題,首選的入口就是分析一下XMPPStream的JID,客戶端在與服務器連接后,Socket就綁定了這個端口,用來處理與服務器的往返數據,認證就是其中之一.而且,往往我們在與服務器來連接的時候,為了簡便,經常使用localhost或者127.0.0.1來當做域名的部分,這時候要尤其注意,因為使用Spark或者其他客戶端程序登錄的時候,使用這樣的域名登錄服務器是沒有問題的,但在代碼中處理就要特別小心,一定要在服務器的后段,確認域名統一:
否則,就會出現本文提示到的這個常見錯誤!!!!!!
// 注: 筆者在第一次遇到這個問題時,整整糾結了一晚上.....😓.