整合Facebook的聊天 [英] Integrating Facebook chat

查看:258
本文介绍了整合Facebook的聊天的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经写了一个程序,Facebook的用户聊天在C#集成,但我总是<失败的xmlns =金塔:IETF:params:一个XML:NS:XMPP协议,SASL><没有授权/>< /失败方式> 发送到服务器的响应后



我检查的API密钥和应用程序的秘密,他们两个都是正确的。它看起来像我传递一些错误的参数给服务器。



下面是我的代码。

 私人无效GetDetailsButton_Click(对象发件人,EventArgs五)
{
TcpClient的FacebookClient =新的TcpClient();
FacebookClient.Connect(chat.facebook.com,5222);
的NetworkStream myns名字= FacebookClient.GetStream();

串XML =< XML版本='1.0'>? +
<流:流+
ID =1+
按钮='chat.facebook.com'+
的xmlns ='胡言乱语:客户'+
的xmlns:流=的http://etherx.jabber.org/streams'+
版本='1.0'>中;

的StreamWriter mySw =新的StreamWriter(myns名字);
mySw.WriteLine(XML); //发送初始请求
mySw.Flush();

字节[] = serverResponseByte新的字节[1024];
INT myBytesRead = 0;
StringBuilder的myResponseAsSB =新的StringBuilder();

//从服务器读取响应看到支持的认证方法

{
myBytesRead = myns.Read(serverResponseByte,0,serverResponseByte.Length);
myResponseAsSB.Append(System.Text.Encoding.UTF8.GetString(serverResponseByte,0,myBytesRead));

},而(myns.DataAvailable);


myResponseAsSB.Clear();

XML =<身份验证+
的xmlns =金塔:IETF:params:一个XML:NS:XMPP协议,SASL'+
机制='X- FACEBOOK平台/>中;

mySw.WriteLine(XML);
mySw.Flush(); //服务器发送响应使用的是X-FACEBOOK平台


//读取由服务器
发送的挑战做
{
myBytesRead = myns名字.Read(serverResponseByte,0,serverResponseByte.Length);
myResponseAsSB.Append(System.Text.Encoding.UTF8.GetString(serverResponseByte,0,myBytesRead));

},而(myns.DataAvailable);


myResponseAsSB.Replace(<挑战的xmlns = \金塔:IETF:params:一个XML:NS:XMPP协议,sasl\>中,);
myResponseAsSB.Replace(< /挑战>,);

//挑战字符串转换为普通字符串
字节[] = myregularstrigbytes Convert.FromBase64String(myResponseAsSB.ToString());
串myregularstring = System.Text.Encoding.UTF8.GetString(myregularstrigbytes);


//我在这里硬编码的accessToken用于测试目的。
串SessionKey = AccessToken.Split('|')[1];

串响应= ComposeResponse(myregularstring);

字节[] = myResponseByte Encoding.UTF8.GetBytes(response.ToString());

串myEncodedResponseToSend = Convert.ToBase64String(myResponseByte);
XML =的String.Format(<响应的xmlns = \金塔:IETF:params:一个XML:NS:XMPP协议,sasl\> {0}< /响应>中,myEncodedResponseToSend);
mySw.WriteLine(XML);
mySw.Flush(); //发送给我的参数

myResponseAsSB.Clear服务器)的响应(;

//检查是否成功,验证

{
myBytesRead = myns.Read(serverResponseByte,0,serverResponseByte.Length);
myResponseAsSB.Append(System.Text.Encoding.UTF8.GetString(serverResponseByte,0,myBytesRead));

},而(myns.DataAvailable);

MessageBox.Show(myResponseAsSB.ToString());

}

私人字符串ComposeResponse(字符串serverresponse)
{
字符串版本= serverresponse.Split('和;')[0] .Split (=)[1];
字符串的方法= serverresponse.Split('和;')[1] .Split('=')[1];
串随机数= serverresponse.Split('和;')。[2] .Split(=)[1];
串SessionKey = AccessToken.Split('|')[1];

长CALLID =(长)(DateTime.UtcNow - 新的日期时间(1970年,1,1))TotalSeconds。

串SIG =API_KEY =+的appid
+CALL_ID =+ CALLID
+的方法=+方法
+随机数=+随机数
+session_key可以=+ SessionKey
+v =+1.0
+ AppSecret;

MD5 MD = MD5.Create();
无功散= md.ComputeHash(Encoding.UTF8.GetBytes(SIG));

SIG = hash.Aggregate(,(目前,B)=>当前+ b.ToString(X2));

返回API_KEY =+ HttpUtility.UrlEncode(APPID)
+&放大器; CALL_ID =+ HttpUtility.UrlEncode(CALLID)
+&放大器;方法=+ HttpUtility.UrlEncode(法)
+&放大器;随机数=+ HttpUtility.UrlEncode(随机数)
+&放大器; session_key可以=+ HttpUtility.UrlEncode(SessionKey)
+&放大器; v =+ HttpUtility.UrlEncode(1.0)
+&放大器; SIG =+ HttpUtility.UrlEncode(SIG);

}



我已经审阅本文章的Facebook在C#的X FACEBOOK聊天认证-platform 和我的应用程序类型是本机/桌面。



可以将某些点我朝着正确的方向吗?



编辑:我认为这个问题是在创建签名,有没有什么办法来验证所创建的签名



修改1:根据这个 SO回答访问令牌包含的第一个后会话密钥|性格和我能找到|性格,直到3天前,但现在我找不到|字符在访问令牌,它真的很奇怪,让我怎么现在发现会话密钥? (或者可能是我应该去睡觉了。)



编辑2:它奇怪的是,我总是得到访问令牌的形式<&APPID GT; |< sessionKey> |<&消化GT; 对本地/桌面应用程序。我做了进一步搜索,发现该会话密钥需要从 auth.promoteSession 提取传统的API和使用的编码参数 HttpUtility.UrlEncode 而不是 HttpUtility.HtmlEncode 的。



现在我已经硬编码的访问令牌(在访问验证它令牌调试),会话密钥,应用程序键和应用程序的秘密我仍然得到同样的错误<失败的xmlns =金塔:IETF:params:一个XML:NS:XMPP协议,SASL> ;<未授权/>< /失败>



修改3:我一直在敲打我的头一个多星期,仍然不起作用,但今天我发现在文档它说一个更新请注意,这需要超过TLS(传输层安全),否则你会得到一个错误。我想我需要相应地修改我的代码。



修改4:我的文档中尝试了代码,发现 $ SESSION_XML 的值应是

  $ SESSION_XML ='<智商TYPE =设置ID =4>'。 
'<会议的xmlns =金塔:IETF:params:一个XML:NS:XMPP协议会/>< / IQ>';



我会后的C#代码,一旦我完成转换了。


< DIV CLASS =h2_lin>解决方案

要使用的X FACEBOOK平台,你需要它设有传统的验证流程的用户会话。
然而,包含的access_token后,用户会话|正如你在EDIT1指出。



我们在最近的博客文章认为ACCESS_TOKEN将被加密宣布,这将是从Octber 1日强制性的。在此之前,该选项可以切换在高级应用程序设置 http://developers.facebook.com/blog/post/ 553 /



展望未来,将的access_token能成为使用用于X FACEBOOK平台。


I have written a program to integrate Facebook user chat in C#, however I always get <failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure> after sending the response to the server.

I've checked the API key and the App secret, both of them are correct. It looks like I'm passing some wrong parameters to the server.

Here is my code.

private void GetDetailsButton_Click(object sender, EventArgs e)
{
     TcpClient FacebookClient = new TcpClient();
     FacebookClient.Connect("chat.facebook.com", 5222);
     NetworkStream myns = FacebookClient.GetStream();

     string xml = "<?xml version='1.0'?>" +
     "<stream:stream " +
     "id='1' " +
     "to='chat.facebook.com' " +
     "xmlns='jabber:client' " +
     "xmlns:stream='http://etherx.jabber.org/streams' " +
     "version='1.0' >";

     StreamWriter mySw = new StreamWriter(myns);
     mySw.WriteLine(xml);  //sending initial request
     mySw.Flush();

     byte[] serverResponseByte = new byte[1024];
     int myBytesRead = 0;
     StringBuilder myResponseAsSB = new StringBuilder();

     //reading response from the server to see the supported authentication methods 
     do
     {
            myBytesRead = myns.Read(serverResponseByte, 0, serverResponseByte.Length);
            myResponseAsSB.Append(System.Text.Encoding.UTF8.GetString(serverResponseByte, 0, myBytesRead));

     } while (myns.DataAvailable);


     myResponseAsSB.Clear();

     xml = "<auth " +
     "xmlns='urn:ietf:params:xml:ns:xmpp-sasl' " +
     "mechanism='X-FACEBOOK-PLATFORM'  />";

     mySw.WriteLine(xml);
     mySw.Flush();   //sending response to server to use X-FACEBOOK-PLATFORM


     //reading challenge send by the server
     do
     {
          myBytesRead = myns.Read(serverResponseByte, 0, serverResponseByte.Length);
          myResponseAsSB.Append(System.Text.Encoding.UTF8.GetString(serverResponseByte, 0, myBytesRead));

     } while (myns.DataAvailable);


     myResponseAsSB.Replace("<challenge xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">", "");
     myResponseAsSB.Replace("</challenge>", "");

     //converting challenge string to normal string
     byte[] myregularstrigbytes = Convert.FromBase64String(myResponseAsSB.ToString());
     string myregularstring = System.Text.Encoding.UTF8.GetString(myregularstrigbytes);


     //I've hardcoded the accesstoken here for testing purpose. 
     string SessionKey = AccessToken.Split('|')[1]; 

     string response = ComposeResponse(myregularstring);

     byte[] myResponseByte = Encoding.UTF8.GetBytes(response.ToString());

     string myEncodedResponseToSend = Convert.ToBase64String(myResponseByte);
     xml = String.Format("<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">{0}</response>", myEncodedResponseToSend);
     mySw.WriteLine(xml);
     mySw.Flush();   //sending the response to the server with my parameters

     myResponseAsSB.Clear();

     //checking if authentication succeed 
     do
     {
          myBytesRead = myns.Read(serverResponseByte, 0, serverResponseByte.Length);
          myResponseAsSB.Append(System.Text.Encoding.UTF8.GetString(serverResponseByte, 0, myBytesRead));

     } while (myns.DataAvailable);

     MessageBox.Show(myResponseAsSB.ToString());

}

    private string ComposeResponse(string serverresponse)
    {
         string version = serverresponse.Split('&')[0].Split('=')[1];
         string method = serverresponse.Split('&')[1].Split('=')[1];
         string nonce = serverresponse.Split('&')[2].Split('=')[1];
         string SessionKey = AccessToken.Split('|')[1];

         long callId = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;

         string sig = "api_key=" + appId
         + "call_id=" + callId
         + "method=" + method
         + "nonce=" + nonce
         + "session_key=" + SessionKey
         + "v=" + "1.0"
         + AppSecret;

         MD5 md = MD5.Create();
         var hash = md.ComputeHash(Encoding.UTF8.GetBytes(sig));

         sig = hash.Aggregate("", (current, b) => current + b.ToString("x2"));

         return "api_key=" + HttpUtility.UrlEncode(appId)
         + "&call_id=" + HttpUtility.UrlEncode(callId)
         + "&method=" + HttpUtility.UrlEncode(method)
         + "&nonce=" + HttpUtility.UrlEncode(nonce)
         + "&session_key=" + HttpUtility.UrlEncode(SessionKey)
         + "&v=" + HttpUtility.UrlEncode("1.0")
         + "&sig=" + HttpUtility.UrlEncode(sig);

    }

I've refereed to this articles Facebook Chat Authentication in C# and X-FACEBOOK-PLATFORM and my application type is of Native/Desktop.

Can some point me in the right direction?

Edit : I think the problem is while creating the signature, is there any way to verify the created signature?

Edit 1 : According to this SO answer the access token contains the session key after the first | character and I could find the | character till 2 days ago, but now I can't find the | character in the access token, its really strange, so how do I find the session key now? (Or may be I should go to sleep now.)

Edit 2 : Its strange that I always got the access token in form of <appId>|<sessionKey>|<digest> for native/desktop application. I did further searching and found out that the session key needs to be extracted from auth.promoteSession legacy api and encode the parameters using HttpUtility.UrlEncode instead of HttpUtility.HtmlEncode.

Now I've hard coded the Access token (verified it in the Access Token Debugger), the session key, App key and app secret still I get the same error <failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure>

Edit 3 : I have been banging my head over a week and still this doesn't work, but today I found a update in the documentation which says Note that this needs to be over TLS (Transport Layer Security) or you'll get an error. I guess I need to modify my code accordingly.

Edit 4 : I've tried out the code in the documentation and found that the value of $SESSION_XML should be

$SESSION_XML = '<iq type="set" id="4">'.
  '<session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></iq>';

I will post the C# code once I finish converting it.

解决方案

To use X-FACEBOOK-PLATFORM you will need the user session which is provided with the legacy auth flow. However, the access_token contain the user session after the | as you noted in your edit1.

We announced in the last blog post that access_token will be encrypted and this will be mandatory from Octber 1st. Until then, the option can be toggle in the Advanced App settings http://developers.facebook.com/blog/post/553/.

Moving forward, access_token will be able to be use for X-FACEBOOK-PLATFORM.

这篇关于整合Facebook的聊天的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆