使用OAUTH 2.0validation并从Facebook cookie获取数据

我有一个用GWT制作的网页。 在那里我使用所有登录facebook的东西与一个被操纵的gwtfb库,一切正常。 迁移到oauth 2.0后,发送到服务器的cookie已更改为加密的cookie。

我想得到一个在服务器中实现的java示例代码与旧代码相同:

  • 我需要像使用cookie md5技巧之前那样validation调用,以了解我的客户端页面是否已进行调用。
  • 从该cookie获取数据:我需要facebook用户。

如果可能不调用FB,只需使用cookie数据。

提前致谢。

好吧,虽然我有一些很好的答案,但我会回答自己在博客中所写的内容: http : //pablocastilla.wordpress.com/2011/09/25/how-to-implement-oauth-f/

现在cookie已经发生了很大变化:它已加密,没有accessstoken,其内容格式发生了很大变化。 在这里你有几个链接谈论它:

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/

因此,要validationcookie,请从中获取用户并获取可以使用此代码的访问令牌:

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

我刚刚将其添加到BatchFB的新版本(2.1.1)中: http : //code.google.com/p/batchfb/

要获取用户ID:

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

你可以在这里看到代码,它使用Jackson解析JSON和javax.crypto.Mac来validation签名:

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

不幸的是,获取访问令牌要复杂得多。 fbsr_ cookie中包含的数据包含一个“代码”,您可以使用该代码进行图形访问以获取真正的访问令牌……您必须将其存储在某个地方的cookie或会话中。 这令人难以置信的蹩脚。

更好的解决方案是从javascript设置您自己的访问令牌cookie。 每次调用FB.getLoginStatus()时,都要设置(或删除)自己的cookie。 您无需担心签署访问令牌,因为它是不可取的。

我认为cookie数据是一种仲裁格式 – 因为你不应该自己解释它? 当然SDK应该为您validationcookie?