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
Facebook: Getting Incorrect Signature (104) when Getting Session Key
提问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
您在帖子和签名中设置的参数存在冲突

