FacebookユーザーチャットをC#に統合するプログラムを作成しました<failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure>
が、サーバーに応答を送信した後に必ず取得します。
APIキーとアプリシークレットを確認しましたが、どちらも正しいです。サーバーに間違ったパラメーターを渡しているようです。
これが私のコードです。
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);
}
この記事を参照しました。C#およびX-FACEBOOK-PLATFORMでのFacebookチャット認証で、アプリケーションの種類はネイティブ/デスクトップです。
誰かが私を正しい方向に向けることができますか?
編集: 問題は署名の作成中にあると思いますが、作成された署名を確認する方法はありますか?
編集1:このSO回答によると、アクセストークンには最初の|の後にセッションキーが含まれています キャラクターと私は|を見つけることができました 2日前まではキャラクターでしたが、今は見つかりません| アクセストークンの文字、それは本当に奇妙です、それで私は今セッションキーをどのように見つけるのですか?(または、私は今寝るべきかもしれません。)
編集2:<appId>|<sessionKey>|<digest>
私が常にネイティブ/デスクトップアプリケーションの形式でアクセストークンを取得したのは奇妙です。さらに検索したところ、セッションキーをauth.promoteSessionレガシーAPIから抽出し、のHttpUtility.UrlEncode
代わりにを使用してパラメーターをエンコードする必要があることがわかりましたHttpUtility.HtmlEncode
。
これで、アクセストークン(アクセストークンデバッガーで確認済み)、セッションキー、アプリキー、アプリシークレットをハードコーディングしましたが、同じエラーが発生します<failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure>
編集3:私は1週間以上頭を叩いてきましたが、それでもこれは機能しませんが、今日、ドキュメントに更新があり、Note that this needs to be over TLS (Transport Layer Security) or you'll get an error.
それに応じてコードを変更する必要があると思います。
編集4:ドキュメントのコードを試してみたところ、の値$SESSION_XML
は
$SESSION_XML = '<iq type="set" id="4">'.
'<session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></iq>';
変換が完了したら、C#コードを投稿します。