XMPP 与 Java Asmack 库和 X-FACEBOOK-PLATFORM
Posted
技术标签:
【中文标题】XMPP 与 Java Asmack 库和 X-FACEBOOK-PLATFORM【英文标题】:XMPP with Java Asmack library and X-FACEBOOK-PLATFORM 【发布时间】:2011-10-17 07:21:12 【问题描述】:我故意复制粘贴this question 不要因为重复而生气。 在这个话题中,我有几个不清楚的时刻:
1)
xmpp.login(apiKey + "|" + sessionKey, sessionSecret, "Application");
sessionKey 是访问令牌的第二部分。如果令牌在 这种形式,AAA|BBB|CCC,BBB 是会话密钥
但我的访问令牌看起来像:BAADcfjCWMLABAIyzRSZA69eAtA9Dr3EQVlXA8Ql6rr5odDWxNYZCHhssiaar8S0gaPLZAm1ZBKCqWO3QFegJPR39hT0JR5ZCyIP1AJZC19qh9mFAExUd9KDjJ05yjE3IUZD
所以我看不到任何“第二部分”...
2)
sessionSecret 是使用旧的 REST API 和方法获得的 auth.promoteSession。要使用它,需要让一个 Http 到达这个 网址:
https://api.facebook.com/method/auth.promoteSession?access_token=yourAccessToken
尽管 Facebook 聊天文档说需要 使用您的应用程序密钥,仅当我使用该密钥时 返回我能够使其工作的 REST 方法。做到这一点 方法有效,您必须禁用 Disable Deprecated Auth Methods 应用程序设置中“高级”选项卡中的选项。
我读过here REST 已被弃用,并且
我们不会在 Graph API 中支持此方法。
我该怎么办?我只使用 Graph API。有没有其他方法可以获取 sessionSecret?
谢谢!
【问题讨论】:
【参考方案1】:我测试了这个,它对我有用。
首先编辑你的 SASLXFacebookPlatformMechanism 类。复制并粘贴此代码。
package com.facebook.android;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import org.apache.harmony.javax.security.auth.callback.CallbackHandler;
import org.apache.harmony.javax.security.sasl.Sasl;
import org.jivesoftware.smack.SASLAuthentication;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.sasl.SASLMechanism;
import org.jivesoftware.smack.util.Base64;
import android.util.Log;
public class SASLXFacebookPlatformMechanism extends SASLMechanism
private static final String NAME = "X-FACEBOOK-PLATFORM";
private String apiKey = "";
private String accessToken = "";
/**
* Constructor.
*/
public SASLXFacebookPlatformMechanism(SASLAuthentication saslAuthentication)
super(saslAuthentication);
@Override
protected void authenticate() throws IOException, XMPPException
getSASLAuthentication().send(new AuthMechanism(NAME, ""));
@Override
public void authenticate(String apiKey, String host, String accessToken) throws IOException, XMPPException
if (apiKey == null || accessToken == null)
throw new IllegalArgumentException("Invalid parameters");
this.apiKey = apiKey;
this.accessToken = accessToken;
this.hostname = host;
String[] mechanisms = "DIGEST-MD5" ;
Map<String, String> props = new HashMap<String, String>();
this.sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, this);
authenticate();
@Override
public void authenticate(String username, String host, CallbackHandler cbh) throws IOException, XMPPException
String[] mechanisms = "DIGEST-MD5" ;
Map<String, String> props = new HashMap<String, String>();
this.sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, cbh);
authenticate();
@Override
protected String getName()
return NAME;
@Override
public void challengeReceived(String challenge) throws IOException
byte[] response = null;
if (challenge != null)
String decodedChallenge = new String(Base64.decode(challenge));
Map<String, String> parameters = getQueryMap(decodedChallenge);
String version = "1.0";
String nonce = parameters.get("nonce");
String method = parameters.get("method");
String composedResponse =
"method=" + URLEncoder.encode(method, "utf-8") +
"&nonce=" + URLEncoder.encode(nonce, "utf-8") +
"&access_token=" + URLEncoder.encode(accessToken, "utf-8") +
"&api_key=" + URLEncoder.encode(apiKey, "utf-8") +
"&call_id=0" +
"&v=" + URLEncoder.encode(version, "utf-8");
response = composedResponse.getBytes();
String authenticationText = "";
if (response != null)
authenticationText = Base64.encodeBytes(response);
// Send the authentication to the server
getSASLAuthentication().send(new Response(authenticationText));
private Map<String, String> getQueryMap(String query)
Map<String, String> map = new HashMap<String, String>();
String[] params = query.split("\\&");
for (String param : params)
String[] fields = param.split("=", 2);
map.put(fields[0], (fields.length > 1 ? fields[1] : null));
return map;
然后在您要登录 facebook 的活动类中使用此方法。
private void testLogin()
ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com", 5222);
config.setSASLAuthenticationEnabled(true);
config.setSecurityMode(ConnectionConfiguration.SecurityMode.enabled);
xmpp = new XMPPConnection(config);
SASLAuthentication.registerSASLMechanism("X-FACEBOOK-PLATFORM",SASLXFacebookPlatformMechanism.class);
SASLAuthentication.supportSASLMechanism("X-FACEBOOK-PLATFORM", 0);
Log.i("XMPPClient",
"Access token to " + mFacebook.getAccessToken());
Log.i("XMPPClient",
"Access token to " + mFacebook.getAppId());
Log.i("XMPPClient",
"Access token to " + mFacebook.getAccessToken());
try
xmpp.connect();
Log.i("XMPPClient",
"Connected to " + xmpp.getHost());
catch (XMPPException e1)
Log.i("XMPPClient",
"Unable to " + xmpp.getHost());
e1.printStackTrace();
try
xmpp.login(PreferenceConnector.APP_ID, mFacebook.getAccessToken());
getRoster(xmpp);
catch (XMPPException e)
e.printStackTrace();
【讨论】:
嗨@JanshairKhan 我正在尝试使用 asmack 库在 android 中的 facebook 上登录上述方法,它给了我一个例外,因为“使用机制 X-FACEBOOK-PLATFORM:SASL 身份验证失败:”,有什么建议吗? 仍然收到“SASL authentication failed using mechanism X-FACEBOOK-PLATFORM:”,以上是关于XMPP 与 Java Asmack 库和 X-FACEBOOK-PLATFORM的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 asmack 版本 asmack-android-8-4.0.6.jar 在 xmpp 中返回组列表