Проверяйте и получайте данные из файлов cookie Facebook, используя OAUTH 2.0 - PullRequest
3 голосов
/ 22 сентября 2011

У меня есть веб-страница, созданная в GWT. Там я использую весь логин в Facebook с манипулированной библиотекой gwtfb, все работает отлично. После перехода на oauth 2.0 теперь файл cookie, отправленный на сервер, изменился на зашифрованный.

Я хочу получить пример кода Java, который реализует на сервере , такой же, как старый:

  • Мне нужно проверить звонок, как я это делал, прежде чем использовать трюк cookie md5, чтобы узнать, был ли звонок сделан моей клиентской страницей.
  • Получить данные из этого cookie: мне нужен пользователь Facebook.

Если возможно, не вызывать FB, просто используя данные cookie.

Заранее спасибо.

Ответы [ 3 ]

8 голосов
/ 26 сентября 2011

Ну, хотя у меня есть несколько хороших ответов, я отвечаю сам себе тем, что написал в своем блоге: http://pablocastilla.wordpress.com/2011/09/25/how-to-implement-oauth-f/

Теперь cookie сильно изменился: он зашифрован, не имеетaccesstoken и его формат контента сильно изменился.Вот несколько ссылок, говорящих об этом:

http://developers.facebook.com/docs/authentication/signed_request/

http://developers.facebook.com/docs/authentication/

http://blog.sociablelabs.com/2011/09/19/server-side-changes-facebook-oauth-2-0-upgrade/

Итак, чтобы проверить куки, получитеПользователь от него и получить токен доступа вы можете использовать этот код:

public class FaceBookSecurity {

// return the fb user in the cookie.
public static String getFBUserFromCookie(HttpServletRequest request)
        throws Exception {
    Cookie fbCookie = getFBCookie(request);

    if (fbCookie == null)
        return null;

    // gets cookie value
    String fbCookieValue = fbCookie.getValue();

    // splits it.
    String[] stringArgs = fbCookieValue.split("\\.");
    String encodedPayload = stringArgs[1];

    String payload = base64UrlDecode(encodedPayload);

    // gets the js object from the cookie
    JsonObject data = new JsonObject(payload);

    return data.getString("user_id");

}

public static boolean ValidateFBCookie(HttpServletRequest request)
        throws Exception {

    Cookie fbCookie = getFBCookie(request);

    if (fbCookie == null)
        throw new NotLoggedInFacebookException();

    // gets cookie information
    String fbCookieValue = fbCookie.getValue();

    String[] stringArgs = fbCookieValue.split("\\.");
    String encodedSignature = stringArgs[0];
    String encodedPayload = stringArgs[1];

    //decode
    String sig = base64UrlDecode(encodedSignature);
    String payload = base64UrlDecode(encodedPayload);

    // gets the js object from the cookie
    JsonObject data = new JsonObject(payload);

    if (!data.getString("algorithm").Equals("HMAC-SHA256")) {
        return false;
    }

    SecretKey key = new SecretKeySpec(
            ApplicationServerConstants.FacebookSecretKey.getBytes(),
            "hmacSHA256");

    Mac hmacSha256 = Mac.getInstance("hmacSHA256");
    hmacSha256.init(key);
    // decode the info.
    byte[] mac = hmacSha256.doFinal(encodedPayload.getBytes());

    String expectedSig = new String(mac);

    // compare if the spected sig is the same than in the cookie.
    return expectedSig.equals(sig);

}

public static String getFBAccessToken(HttpServletRequest request)
        throws Exception {
    Cookie fbCookie = getFBCookie(request);

    String fbCookieValue = fbCookie.getValue();

    String[] stringArgs = fbCookieValue.split("\\.");
    String encodedPayload = stringArgs[1];

    String payload = base64UrlDecode(encodedPayload);

    // gets the js object from the cookie
    JsonObject data = new JsonObject(payload);

    String authUrl = getAuthURL(data.getString("code"));
    URL url = new URL(authUrl);
    URI uri = new URI(url.getProtocol(), url.getHost(), url.getPath(),
            url.getQuery(), null);
    String result = readURL(uri.toURL());

    String[] resultSplited = result.split("&");

    return resultSplited[0].split("=")[1];

}

// creates the url for calling to oauth.
public static String getAuthURL(String authCode) {
    String url = "https://graph.facebook.com/oauth/access_token?client_id="
            + ApplicationConstants.FacebookApiKey
            + "&redirect_uri=&client_secret="
            + ApplicationServerConstants.FacebookSecretKey + "&code="
            + authCode;

    return url;
}

// reads the url.
private static String readURL(URL url) throws IOException {

    InputStream is = url.openStream();

    InputStreamReader inStreamReader = new InputStreamReader(is);
    BufferedReader reader = new BufferedReader(inStreamReader);

    String s = "";

    int r;
    while ((r = is.read()) != -1) {
        s = reader.readLine();
    }

    reader.close();
    return s;
}

private static String base64UrlDecode(String input) {
    String result = null;
    Base64 decoder = new Base64(true);
    byte[] decodedBytes = decoder.decode(input);
    result = new String(decodedBytes);
    return result;
}

    private static Cookie getFBCookie(HttpServletRequest request) 
    {
        Cookie[] cookies = request.getCookies();

        if (cookies == null)
            return null;

        Cookie fbCookie = null;

        for (Cookie c : cookies) {
            if (c.getName().equals(
                "fbsr_" + ApplicationServerConstants.FacebookApiKey)) {
                fbCookie = c;
            }
        }
        return fbCookie;
    }
}
2 голосов
/ 25 сентября 2011

Я только что добавил это в новую версию (2.1.1) BatchFB: http://code.google.com/p/batchfb/

Чтобы получить идентификатор пользователя:

FacebookCookie data = FacebookCookie.decode(cookie, YOURAPPSECRET);
System.out.println("Facebook user id is " + data.getFbId());

Вы можете увидеть код здесь,который использует Джексона для анализа JSON и javax.crypto.Mac для проверки подписи:

http://code.google.com/p/batchfb/source/browse/trunk/src/com/googlecode/batchfb/FacebookCookie.java

К сожалению, получить токен доступа значительно сложнее.Данные, которые входят в cookie-файл fbsr_, включают в себя «код», который вы затем можете использовать для получения api-графика графа для получения реального токена доступа ... который вы должны будете где-то сохранить в файле cookie или сеансе.Это невероятно неубедительно.

Лучшее решение - установить свой собственный cookie-файл токена доступа из javascript.Каждый раз, когда вы вызываете FB.getLoginStatus (), вы должны установить (или удалить) свой собственный файл cookie.Вам не нужно беспокоиться о подписании токена доступа, так как он неуязвим.

1 голос
/ 22 сентября 2011

Я думаю, что данные cookie находятся в произвольном формате - потому что вы не должны интерпретировать их самостоятельно?Конечно, SDK должен проверять cookie для вас?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...