java Facebook:获取会话密钥时获取错误签名 (104)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1409220/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 16:27:15  来源:igfitidea点击:

Facebook: Getting Incorrect Signature (104) when Getting Session Key

javafacebookrestjunithttpclient

提问by mw_javaguy

I am trying to use the HttpClientlibrary (in order to call the Facebook API's REST end points) to obtain a session key and verify user...

我正在尝试使用HttpClient库(为了调用 Facebook API 的 REST 端点)来获取会话密钥并验证用户...

My code is here:

我的代码在这里:

RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations =
{ "classpath*:**/*applicationContext-test.xml" })
public class FacebookUserTest
{
    final String API_KEY = "9e2568d68f182a2957878f3acedd9453";
    final String SECRET = "f1298956895d39110be92a672e0d2284";
    final String TOKEN = "aa0c41aa4532053e8d0097844ab9bc7d";
    final String LOGIN = "http://www.facebook.com/login.php";
    final String HOST = "http://www.facebook.com/restserver.php";

    private static Logger log = 
        LoggerFactory.getLogger(FacebookUserTest.class);

    protected FacebookUser FacebookUser;

    @Test
    public void testFindUserBySessionKey() throws Exception
    {
        loginToFacebook();
        String sessionKey = getSessionKey();
    }

    public void loginToFacebook() throws Exception
    {
        HttpClient client = new HttpClient();
        client.setParams(new HttpClientParams());
        client.setState(new HttpState());

        GetMethod get = new GetMethod(LOGIN + "?api_key=" + API_KEY
            + "&v=1.0&auth_token=" + TOKEN);

        // Get login screen
        client.executeMethod(get);

        // Post credentials to login
        PostMethod post = new PostMethod(LOGIN);
        post.addParameter(new NameValuePair("api_key", API_KEY));
        post.addParameter(new NameValuePair("v", "1.0"));
        post.addParameter(new NameValuePair("auth_token", TOKEN));
        post.addParameter(new NameValuePair("email", "[email protected]"));
        post.addParameter(new NameValuePair("pass", "password"));
        client.executeMethod(post);
    }

    public String getSessionKey() throws Exception
    {
        HttpClient client = new HttpClient();

        // Obtain session key
        String host = "http://www.facebook.com/restserver.php";
        String sessSecret = "false";
        String toMd = "api_key=" + API_KEY + "auth_token=" + TOKEN
            + "format=xmlgenerate_session_secret=" + sessSecret
            + "method=facebook.auth.getSessionv=1.0" + SECRET;
         String md5 = Md5Utils.MD5(toMd);

         PostMethod post = new PostMethod(HOST);

         NameValuePair[] data = {
            new NameValuePair("api_key", API_KEY),
            new NameValuePair("auth_token", TOKEN),
            new NameValuePair("format", "xml"),
            new NameValuePair("generate_session_secret", SECRET),
            new NameValuePair("method", "auth.getSession"),
            new NameValuePair("sig", md5), new NameValuePair("v", "1.0")
         };

         post.setRequestBody(data);
         post.setRequestHeader("Content-Type",
            "application/x-www-form-urlencoded");
         post.setRequestHeader("User-Agent",
            "Facebook API PHP5 Client 1.1 (curl) 5");

         // execute method and handle any error responses.
         client.executeMethod(post);

         StringBuilder sb = new StringBuilder();
         byte[] b = new byte[4096];

         for (int n; (n = post.getResponseBodyAsStream().read(b)) != -1;) 
         {
             sb.append(new String(b, 0, n));
         }

         String sessionId = sb.toString();
         log.warn("Session Id: " + sessionId);

         return sessionId;
     }
}

When I run my JUnit test, this is what is printed from the console:

当我运行 JUnit 测试时,这是从控制台打印的内容:

WARN : com.myapp.FacebookUserTest - Session Id: 

<?xml version="1.0" encoding="UTF-8"?>
<error_response xmlns="http://api.facebook.com/1.0/" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://api.facebook.com/1.0/
   http://api.facebook.com/1.0/facebook.xsd">
    <error_code>104</error_code>
    <error_msg>Incorrect signature</error_msg>
    <request_args list="true">
        <arg>
            <key>api_key</key>
            <value>9e2568d68f182a2957878f3acedd9453</value>
        </arg>
        <arg>
            <key>auth_token</key>
            <value>aa0c41aa4532053e8d0097844ab9bc7d</value>
        </arg>
        <arg>
            <key>format</key>
            <value>xml</value>
        </arg>
        <arg>
            <key>generate_session_secret</key>
            <value>f1298956895d39110be92a672e0d2284</value>
         </arg>
         <arg>
            <key>method</key>
            <value>auth.getSession</value>
         </arg>
         <arg>
             <key>sig</key>
             <value>fcf80d658f35d66396ac521da7102782</value>
         </arg>
         <arg>
             <key>v</key>
             <value>1.0</value>
          </arg>
     </request_args>
</error_response>

Could it be my MD5Utils code:

难道是我的 MD5Utils 代码:

 public class Md5Utils
 {
      private static String convertToHex(byte[] data)
      {
           StringBuffer buf = new StringBuffer();
           for (int i = 0; i < data.length; i++) {
               int halfbyte = (data[i] >>> 4) & 0x0F;
               int two_halfs = 0;
               do {
                   if ((0 <= halfbyte) && (halfbyte <= 9))
                       buf.append((char) ('0' + halfbyte));
                   else
                      buf.append((char) ('a' + (halfbyte - 10)));
                      halfbyte = data[i] & 0x0F;
               }
               while (two_halfs++ < 1);
            }
        return buf.toString();
      }

  public static String MD5(String text) 
  throws NoSuchAlgorithmException, UnsupportedEncodingException {
      MessageDigest md;
      md = MessageDigest.getInstance("MD5");
      byte[] md5hash = new byte[32];
      md.update(text.getBytes("iso-8859-1"), 0, text.length());
      md5hash = md.digest();
      return convertToHex(md5hash);
   }
}

What am I possibly doing wrong to generate an incorrect signature?

我可能做错了什么来生成不正确的签名?

Would really appreciate it if someone could help me or point me in the right direction...

如果有人可以帮助我或为我指明正确的方向,我将不胜感激...

Happy programming and thanks for reading!

编程愉快,感谢阅读!

回答by fyasar

Try this

试试这个

    string GenerateSignature(IDictionary<string, string> parameters)
    {
        StringBuilder signatureBuilder = new StringBuilder();

        // Sort the keys of the method call in alphabetical order
        List<string> keyList = ParameterDictionaryToList(parameters);
        keyList.Sort();

        // Append all the parameters to the signature input paramaters
        foreach (string key in keyList)
            signatureBuilder.Append(String.Format(CultureInfo.InvariantCulture, "{0}={1}", key, parameters[key]));

        // Append the secret to the signature builder
        signatureBuilder.Append(ConfigurationManager.AppSettings["FBApiSecret"]);

        MD5 md5 = MD5.Create();
        // Compute the MD5 hash of the signature builder
        byte[] hash = md5.ComputeHash(Encoding.UTF8.GetBytes(signatureBuilder.ToString().Trim()));

        // Reinitialize the signature builder to store the actual signature
        signatureBuilder = new StringBuilder();

        // Append the hash to the signature
        foreach (byte hashByte in hash)
            signatureBuilder.Append(hashByte.ToString("x2", CultureInfo.InvariantCulture));

        return signatureBuilder.ToString();
    }

    string CreateHTTPParameterList(IDictionary<string, string> parameterList)
    {
        StringBuilder queryBuilder = new StringBuilder();
        parameterList.Add("api_key", ConfigurationManager.AppSettings["FBApiKey"]);
        parameterList.Add("v", "1.0");
        parameterList.Add("call_id", DateTime.Now.Ticks.ToString("x", CultureInfo.InvariantCulture));
        parameterList.Add("sig", GenerateSignature(parameterList));
        //parameterList.Add("sig", _sig);

        // Build the query
        foreach (KeyValuePair<string, string> kvp in parameterList)
        {
            queryBuilder.Append(kvp.Key);
            queryBuilder.Append("=");
            queryBuilder.Append(HttpUtility.UrlEncode(kvp.Value));
            queryBuilder.Append("&");
        }
        queryBuilder.Remove(queryBuilder.Length - 1, 1);

        return queryBuilder.ToString();
    }

Example usage :

示例用法:

        Dictionary<string, string> parameterList = new Dictionary<string, string>();
        parameterList.Add("auth_token", authCode);
        parameterList.Add("format", "json");
        parameterList.Add("method", "facebook.auth.getSession");

        string req = CreateHTTPParameterList(parameterList);

I tryed to copy / paste these codes from my old project. I hope it will be help to you.

我试图从我的旧项目中复制/粘贴这些代码。我希望它会对你有所帮助。

回答by Omnia

you have an error in your parameter you send in generate_session_secret your secret code , it must be true or false

您在 generate_session_secret 中发送的参数中有错误您的密码,它必须是 true 或 false

you set: new NameValuePair("generate_session_secret", SECRET),

你设置: new NameValuePair("generate_session_secret", SECRET),

there are conflict in your parameter that u set in post and the signature

您在帖子和签名中设置的参数存在冲突