XMPP con la biblioteca Java Asmack compatible con X-FACEBOOK-PLATFORM

16 minutos de lectura

XMPP con la biblioteca Java Asmack compatible con X-FACEBOOK-PLATFORM
Adrián

Estoy tratando de hacer un chat de Facebook en Android con la biblioteca Smack. he leído el API de chat de Facebook, pero no puedo entender cómo tengo que autenticarme con Facebook usando esta biblioteca.

¿Alguien puede indicarme cómo lograr esto?

Actualizar: Según la respuesta de no.good.at.coding, tengo este código adaptado a la biblioteca de Asmack. Todo funciona bien excepto que recibo como respuesta al inicio de sesión: no autorizado. Aquí está el código que uso:

public class SASLXFacebookPlatformMechanism extends SASLMechanism
{

    private static final String NAME              = "X-FACEBOOK-PLATFORM";

    private String              apiKey            = "";
    private String              applicationSecret = "";
    private String              sessionKey        = "";

    /**
     * Constructor.
     */
    public SASLXFacebookPlatformMechanism(SASLAuthentication saslAuthentication)
    {
        super(saslAuthentication);
    }

    @Override
    protected void authenticate() throws IOException, XMPPException
    {

        getSASLAuthentication().send(new AuthMechanism(NAME, ""));
    }

    @Override
    public void authenticate(String apiKeyAndSessionKey, String host,
            String applicationSecret) throws IOException, XMPPException
    {
        if (apiKeyAndSessionKey == null || applicationSecret == null)
        {
            throw new IllegalArgumentException("Invalid parameters");
        }

        String[] keyArray = apiKeyAndSessionKey.split("\|", 2);
        if (keyArray.length < 2)
        {
            throw new IllegalArgumentException(
                    "API key or session key is not present");
        }

        this.apiKey = keyArray[0];
        Log.d("API_KEY", apiKey);
        this.applicationSecret = applicationSecret;
        Log.d("SECRET_KEY", applicationSecret);
        this.sessionKey = keyArray[1];
        Log.d("SESSION_KEY", sessionKey);

        this.authenticationId = sessionKey;
        this.password = applicationSecret;
        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
    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));
            Log.d("DECODED", decodedChallenge);
            Map<String, String> parameters = getQueryMap(decodedChallenge);

            String version = "1.0";
            String nonce = parameters.get("nonce");
            String method = parameters.get("method");

            long callId = new GregorianCalendar().getTimeInMillis() / 1000L;

            String sig =
                    "api_key=" + apiKey + "call_id=" + callId + "method="
                            + method + "nonce=" + nonce + "session_key="
                            + sessionKey + "v=" + version + applicationSecret;

            try
            {
                sig = md5(sig);
                sig = sig.toUpperCase();
            } catch (NoSuchAlgorithmException e)
            {
                throw new IllegalStateException(e);
            }

            String composedResponse =
                    "api_key=" + URLEncoder.encode(apiKey, "utf-8")
                            + "&call_id=" + callId + "&method="
                            + URLEncoder.encode(method, "utf-8") + "&nonce="
                            + URLEncoder.encode(nonce, "utf-8")
                            + "&session_key="
                            + URLEncoder.encode(sessionKey, "utf-8") + "&v="
                            + URLEncoder.encode(version, "utf-8") + "&sig="
                            + URLEncoder.encode(sig, "utf-8");

            Log.d("COMPOSED", composedResponse);

            response = composedResponse.getBytes("utf-8");
        }

        String authenticationText = "";

        if (response != null)
        {
            authenticationText =
                    Base64.encodeBytes(response, Base64.DONT_BREAK_LINES);
        }

        // 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;
    }

    private String md5(String text) throws NoSuchAlgorithmException,
            UnsupportedEncodingException
    {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(text.getBytes("utf-8"), 0, text.length());
        return convertToHex(md.digest());
    }

    private String convertToHex(byte[] data)
    {
        StringBuilder buf = new StringBuilder();
        int len = data.length;

        for (int i = 0; i < len; i++)
        {
            int halfByte = (data[i] >>> 4) & 0xF;
            int twoHalfs = 0;

            do
            {
                if (0 <= halfByte && halfByte <= 9)
                {
                    buf.append((char) ('0' + halfByte));
                }
                else
                {
                    buf.append((char) ('a' + halfByte - 10));
                }
                halfByte = data[i] & 0xF;
            } while (twoHalfs++ < 1);
        }

        return buf.toString();
    }
}

Y esta, es la comunicación con el servidor con los mensajes enviados y recibidos:

PM SENT (1132418216): <stream:stream to="chat.facebook.com" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" version="1.0">


PM RCV  (1132418216): <?xml version="1.0"?><stream:stream id="C62D0F43" from="chat.facebook.com" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" version="1.0" xml:lang="en"><stream:features><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>X-FACEBOOK-PLATFORM</mechanism><mechanism>DIGEST-MD5</mechanism></mechanisms></stream:features>


PM SENT (1132418216): <auth mechanism="X-FACEBOOK-PLATFORM" xmlns="urn:ietf:params:xml:ns:xmpp-sasl"></auth>


PM RCV  (1132418216): <challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">dmVyc2lvbj0xJm1ldGhvZD1hdXRoLnhtcHBfbG9naW4mbm9uY2U9NzFGNkQ3Rjc5QkIyREJCQ0YxQTkwMzA0QTg3OTlBMzM=</challenge>


PM SENT (1132418216): <response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">YXBpX2tleT0zMWYzYjg1ZjBjODYwNjQ3NThiZTZhOTQyNjVjZmNjMCZjYWxsX2lkPTEzMDA0NTYxMzUmbWV0aG9kPWF1dGgueG1wcF9sb2dpbiZub25jZT03MUY2RDdGNzlCQjJEQkJDRjFBOTAzMDRBODc5OUEzMyZzZXNzaW9uX2tleT0yNjUzMTg4ODNkYWJhOGRlOTRiYTk4ZDYtMTAwMDAwNTAyNjc2Nzc4JnY9MS4wJnNpZz04RkRDRjRGRTgzMENGOEQ3QjgwNjdERUQyOEE2RERFQw==</response>


PM RCV  (1132418216): <failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure>

Como se lee en el foro de desarrolladores en facebook, es necesario deshabilitar la configuración “Deshabilitar métodos de autenticación obsoletos” en la página de configuración de Facebook de su aplicación. Pero, incluso haciendo eso, no puedo iniciar sesión. Y la clave de sesión es la segunda parte del token OAuth en la forma AAA|BBB|CCC, quiero decir, BBB.

  • java.security.KeyStoreException: no se encontró la implementación de KeyStore jks

    – Bhavesh Hirpara

    18 oct.

  • No lo use. El chat xmpp de Facebook no estará disponible después del 30 de abril de 2015. developers.facebook.com/docs/apps/changelog

    – Jaspreet Chabra

    02 mar. 15 a las 0:15

Finalmente, gracias al código no.good.at.coding y la sugerencia de harism, he podido conectarme al chat de Facebook. Este código es el mecanismo para la biblioteca Asmack (el puerto Smack para Android). Para la librería Smack es necesario utilizar el mecanismo no.good.at.coding.

SASLXFacebookPlatformMechanism.java:

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;

public class SASLXFacebookPlatformMechanism extends SASLMechanism
{

    private static final String NAME              = "X-FACEBOOK-PLATFORM";

    private String              apiKey            = "";
    private String              applicationSecret = "";
    private String              sessionKey        = "";

    /**
     * Constructor.
     */
    public SASLXFacebookPlatformMechanism(SASLAuthentication saslAuthentication)
    {
        super(saslAuthentication);
    }

    @Override
    protected void authenticate() throws IOException, XMPPException
    {

        getSASLAuthentication().send(new AuthMechanism(NAME, ""));
    }

    @Override
    public void authenticate(String apiKeyAndSessionKey, String host,
            String applicationSecret) throws IOException, XMPPException
    {
        if (apiKeyAndSessionKey == null || applicationSecret == null)
        {
            throw new IllegalArgumentException("Invalid parameters");
        }

        String[] keyArray = apiKeyAndSessionKey.split("\|", 2);
        if (keyArray.length < 2)
        {
            throw new IllegalArgumentException(
                    "API key or session key is not present");
        }

        this.apiKey = keyArray[0];
        this.applicationSecret = applicationSecret;
        this.sessionKey = keyArray[1];

        this.authenticationId = sessionKey;
        this.password = applicationSecret;
        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");

            long callId = new GregorianCalendar().getTimeInMillis();

            String sig =
                    "api_key=" + apiKey + "call_id=" + callId + "method="
                            + method + "nonce=" + nonce + "session_key="
                            + sessionKey + "v=" + version + applicationSecret;

            try
            {
                sig = md5(sig);
            } catch (NoSuchAlgorithmException e)
            {
                throw new IllegalStateException(e);
            }

            String composedResponse =
                    "api_key=" + URLEncoder.encode(apiKey, "utf-8")
                            + "&call_id=" + callId + "&method="
                            + URLEncoder.encode(method, "utf-8") + "&nonce="
                            + URLEncoder.encode(nonce, "utf-8")
                            + "&session_key="
                            + URLEncoder.encode(sessionKey, "utf-8") + "&v="
                            + URLEncoder.encode(version, "utf-8") + "&sig="
                            + URLEncoder.encode(sig, "utf-8");

            response = composedResponse.getBytes("utf-8");
        }

        String authenticationText = "";

        if (response != null)
        {
            authenticationText =
                    Base64.encodeBytes(response, Base64.DONT_BREAK_LINES);
        }

        // 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;
    }

    private String md5(String text) throws NoSuchAlgorithmException,
            UnsupportedEncodingException
    {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(text.getBytes("utf-8"), 0, text.length());
        return convertToHex(md.digest());
    }

    private String convertToHex(byte[] data)
    {
        StringBuilder buf = new StringBuilder();
        int len = data.length;

        for (int i = 0; i < len; i++)
        {
            int halfByte = (data[i] >>> 4) & 0xF;
            int twoHalfs = 0;

            do
            {
                if (0 <= halfByte && halfByte <= 9)
                {
                    buf.append((char) ('0' + halfByte));
                }
                else
                {
                    buf.append((char) ('a' + halfByte - 10));
                }
                halfByte = data[i] & 0xF;
            } while (twoHalfs++ < 1);
        }

        return buf.toString();
    }
}

Para usarlo:

ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com", 5222);
config.setSASLAuthenticationEnabled(true);
XMPPConnection xmpp = new XMPPConnection(config);
try
{
    SASLAuthentication.registerSASLMechanism("X-FACEBOOK-PLATFORM", SASLXFacebookPlatformMechanism.class);
    SASLAuthentication.supportSASLMechanism("X-FACEBOOK-PLATFORM", 0);
    xmpp.connect();
    xmpp.login(apiKey + "|" + sessionKey, sessionSecret, "Application");
} catch (XMPPException e)
{
    xmpp.disconnect();
    e.printStackTrace();
}

apiKey es la clave API proporcionada en la página de configuración de la aplicación en Facebook. sessionKey es la segunda parte del token de acceso. Si el token tiene este formato, AAA|BBB|CCC, el BBB es la clave de sesión. sessionSecret se obtiene utilizando la antigua API REST con el método auth.promoteSession. Para usarlo, es necesario hacer que un Http llegue a esta url:

https://api.facebook.com/method/auth.promoteSession?access_token=yourAccessToken

A pesar de que la documentación de Facebook Chat dice que es necesario usar la clave secreta de su aplicación, solo cuando usé la clave que devolvió ese método REST pude hacerlo funcionar. Para que ese método funcione, debe deshabilitar el Deshabilitar métodos de autenticación obsoletos opción en la pestaña Avanzado en la configuración de su aplicación.

  • Gracias por su respuesta. ¿A qué access_token te refieres? Mi token de acceso, obtenido con el SDK de gráficos de Facebook para Android, no tiene conductos, por lo que no estoy seguro de cómo obtener la clave de sesión. Intenté usar todo el access_token, pero obtengo una excepción XMPP de que no estoy autenticado.

    – Desgaste mate

    15 jun.

  • Muy bien, estoy bastante seguro de que lo hice funcionar. Todo lo que tenía que hacer era esto: xmpp.login(, sessionSecret, “Application”); ¡Muchas gracias! Gran código, ¡vota!

    – Desgaste mate

    15 jun.

  • No sé por qué recibes ese error, pero mi chat funciona bien. La biblioteca funciona bien, si ha usado mi código, se supone que debe ingresar la clave api + la clave de sesión separadas por una tubería como el primer parámetro en el método de inicio de sesión de XMPPConnection.

    – Adrián

    16 jun.

  • @MattWear Una vez es suficiente. Pero, cada vez que cambia el token de acceso, debe obtener un nuevo sessionSecret.

    – Adrián

    27 jun.


  • su código muy útil. Lo modifiqué un poco para usar solo apiKey y accessToken sin applicationSecret y sessionKey ya que la API de chat actual solo toma access_token y apiKey.

    – Amal

    07 feb.

Usé esto hace unos 6 meses con Smack (no asmack), así que no estoy seguro de cómo se mantendrá ahora, pero aquí va, ¡espero que ayude!

Encontré una implementación del mecanismo de autenticación X-FACEBOOK-PLATFORM de Facebook en el Ignite Realtime Smack foro de dónde alguien lo sacó proyecto fbgc. Encontrarás el ZIP con el SASLXFacebookPlatformMechanism.java fuente en la respuesta a la que me vinculé. Puedes usarlo de la siguiente manera:

public void login() throws XMPPException
{
    SASLAuthentication.registerSASLMechanism(SASLXFacebookPlatformMechanism.NAME,
            SASLXFacebookPlatformMechanism.class);
    SASLAuthentication.supportSASLMechanism(SASLXFacebookPlatformMechanism.NAME, 0);

    ConnectionConfiguration connConfig = new ConnectionConfiguration(host, port);

    XMPPConnection connection = new XMPPConnection(connConfig);
    connection.connect();
    log.info("XMPP client connected");

    connection.login(Utils.FB_APP_ID + "|" + this.user.sessionId, Utils.FB_APP_SECRET, "app_name");
    log.info("XMPP client logged in");
}

Estaba haciendo esto en el servidor sin un SDK. No recuerdo los detalles (y la documentación de Facebook no es muy buena), pero por lo que puedo ver en mi código, después de que el usuario autorice la aplicación, recibo una solicitud de devolución de llamada de Facebook con un code parámetro. abro un URLConnection a https://graph.facebook.com/oauth/access_token?client_id=<app_id>&redirect_uri=http://myserver/context/path/&client_secret=<app_secret>&code=<code>. La respuesta debe ser el token de acceso donde la identificación de la sesión es la parte posterior a la | – algo de la forma XXX|<sessionId>.

Aquí está el código que he estado usando con éxito para la autenticación. Tal vez esto ayude a pesar de que esto no está relacionado con Smack de ninguna manera. Puede obtener sessionKey del token de acceso recibido de FB, y para obtener sessionSecret, he estado usando la API REST antigua;

http://developers.facebook.com/docs/reference/rest/auth.promoteSession/

private final void processChallenge(XmlPullParser parser, Writer writer,
        String sessionKey, String sessionSecret) throws IOException,
        NoSuchAlgorithmException, XmlPullParserException {

    parser.require(XmlPullParser.START_TAG, null, "challenge");
    String challenge = new String(Base64.decode(parser.nextText(),
            Base64.DEFAULT));

    String params[] = challenge.split("&");
    HashMap<String, String> paramMap = new HashMap<String, String>();
    for (int i = 0; i < params.length; ++i) {
        String p[] = params[i].split("=");
        p[0] = URLDecoder.decode(p[0]);
        p[1] = URLDecoder.decode(p[1]);
        paramMap.put(p[0], p[1]);
    }

    String api_key = "YOUR_API_KEY";
    String call_id = "" + System.currentTimeMillis();
    String method = paramMap.get("method");
    String nonce = paramMap.get("nonce");
    String v = "1.0";

    StringBuffer sigBuffer = new StringBuffer();
    sigBuffer.append("api_key=" + api_key);
    sigBuffer.append("call_id=" + call_id);
    sigBuffer.append("method=" + method);
    sigBuffer.append("nonce=" + nonce);
    sigBuffer.append("session_key=" + sessionKey);
    sigBuffer.append("v=" + v);
    sigBuffer.append(sessionSecret);

    MessageDigest md = MessageDigest.getInstance("MD5");
    md.update(sigBuffer.toString().getBytes());
    byte[] digest = md.digest();

    StringBuffer sig = new StringBuffer();
    for (int i = 0; i < digest.length; ++i) {
        sig.append(Integer.toHexString(0xFF & digest[i]));
    }

    StringBuffer response = new StringBuffer();
    response.append("api_key=" + URLEncoder.encode(api_key));
    response.append("&call_id=" + URLEncoder.encode(call_id));
    response.append("&method=" + URLEncoder.encode(method));
    response.append("&nonce=" + URLEncoder.encode(nonce));
    response.append("&session_key=" + URLEncoder.encode(sessionKey));
    response.append("&v=" + URLEncoder.encode(v));
    response.append("&sig=" + URLEncoder.encode(sig.toString()));

    StringBuilder out = new StringBuilder();
    out.append("<response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">");
    out.append(Base64.encodeToString(response.toString().getBytes(),
            Base64.NO_WRAP));
    out.append("</response>");

    writer.write(out.toString());
    writer.flush();
}

  • ¡¡Gracias!! ¡Ese método REST funcionó! Estaba usando la clave secreta que tengo en la página de configuración de mi aplicación, pero cuando probé el resultado de ese método, la clave de sesión comenzó a funcionar. Como voy a poner el código que funciona con la biblioteca Asmack/Smack, no marcaré tu respuesta como aceptada, pero la he votado. Realmente te agradezco tu consejo.

    – Adrián

    30 abr.

Lamento hacer una nueva respuesta, pero tuve que incluir el nuevo código @YShinkarev, lo siento por llegar tarde.
Al modificar la respuesta de @Adrian para hacer challengeReceived, podemos usar APIKey y accessToken, todo lo que modifiqué fue la respuesta compuesta

@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");

        long callId = new GregorianCalendar().getTimeInMillis();

        String composedResponse = "api_key="
                + URLEncoder.encode(apiKey, "utf-8") + "&call_id=" + callId
                + "&method=" + URLEncoder.encode(method, "utf-8")
                + "&nonce=" + URLEncoder.encode(nonce, "utf-8")
                + "&access_token="
                + URLEncoder.encode(access_token, "utf-8") + "&v="
                + URLEncoder.encode(version, "utf-8");

        response = composedResponse.getBytes("utf-8");
    }

    String authenticationText = "";

    if (response != null) {
        authenticationText = Base64.encodeBytes(response,
                Base64.DONT_BREAK_LINES);
    }

    // Send the authentication to the server
    getSASLAuthentication().send(new Response(authenticationText));
}

¿Qué es lo que quieres hacer?

Si solo desea iniciar sesión en el chat de FB, se conecta a FB como cualquier otro servidor XMPP.

Miraría y usaría “Autenticación con nombre de usuario/contraseña” de Chat API, que es compatible con Smack. A menos que me gustaría escribir una aplicación de FaceBook. Luego intentaría iniciar sesión con “Autenticación con la plataforma de Facebook”.

Entonces, solo use Smack para conectarse al chat de FB como lo haría con su cliente Jabber común.

  1. Para el nombre de usuario, use su Facebook nombre de usuario. (ver http://www.facebook.com/nombre de usuario/ )
  2. Para el dominio, utilice: chat.facebook.com
  3. Para la contraseña, usa tu Facebook contraseña
  4. Turno apagado SSL y TSL
  5. Establezca el puerto de conexión en: 5222 (que es el valor predeterminado para XMPP)
  6. Establecer conectar servidor a chat.facebook.com

  • Gracias por su respuesta. La API de chat de Facebook dice que si su aplicación (estoy programando un cliente de Facebook) tiene una ID de aplicación de Facebook, debe usar la otra autenticación de chat (X-FACEBOOK-PLATFORM). Esa es la razón por la que no uso el mecanismo DIGEST-MD5. ¿Sabes cómo apoyar la PLATAFORMA X-FACEBOOK en Smack?

    – Adrián

    16 mar. 11 en 11:43


  • Lo siento, soy más un programador de clientes XMPP 🙂 Así que no lo he probado. Pero como escribiste, si escribes un cliente FB debes usar X-FACEBOOK-PLATFORM ya que sus usuarios no deberían necesitar iniciar sesión una vez más desde la página web cuando usan su aplicación. Hay una nueva versión de Smack en camino que está actualizada y debería corregir algunos errores que podría ser un problema para ti. Algunos de ellos han sido corregidos por asmack. Buscaría la solución de ‘no.goog.at.coding’, ya que consiguió que funcionara en un punto. 😉

    – Anders

    12 abr.


  • Gracias por su respuesta. La API de chat de Facebook dice que si su aplicación (estoy programando un cliente de Facebook) tiene una ID de aplicación de Facebook, debe usar la otra autenticación de chat (X-FACEBOOK-PLATFORM). Esa es la razón por la que no uso el mecanismo DIGEST-MD5. ¿Sabes cómo apoyar la PLATAFORMA X-FACEBOOK en Smack?

    – Adrián

    16 mar. 11 en 11:43


  • Lo siento, soy más un programador de clientes XMPP 🙂 Así que no lo he probado. Pero como escribiste, si escribes un cliente FB debes usar X-FACEBOOK-PLATFORM ya que sus usuarios no deberían necesitar iniciar sesión una vez más desde la página web cuando usan su aplicación. Hay una nueva versión de Smack en camino que está actualizada y debería corregir algunos errores que podría ser un problema para ti. Algunos de ellos han sido corregidos por asmack. Buscaría la solución de ‘no.goog.at.coding’, ya que consiguió que funcionara en un punto. 😉

    – Anders

    12 abr.


.

¿Ha sido útil esta solución?