我正在尝试设置原型环境并与 facebook 进行通信。我已经设置了一个测试 Java 应用程序,并通过我的静态 IP 提供服务。对于 facebook 部分,我已经实现了这个朋友的例子
http://www.richardnichols.net/2010/06/implementing-facebook-oauth-2-0-authentication-in-java/
为了解决您可能对与 facebook 的一般连接性的任何问题,我已经使用以下信息启动了我自己的页面选项卡应用程序
页面标签 URL:http://[MYIP]:8080/facebookContest/app/index.do 安全页面标签 URL:https://[MYIP]:8443/facebookContest/app/index.do
我已经检查了这两个 url 是否都可以正常工作,并且确实返回了我的“hello world”localy。我将此应用程序添加到我创建的测试 facebook 页面,使用此 url: http ://www.facebook.com/dialog/pagetab?app_id=[MYAPPID]&next=http://[MYIP]:8080/facebookContest/应用程序/index.do
仅供参考,如果我禁用所有 facebook 授权/通信逻辑,应用程序的静态内容会在 facebook 内正确显示。因此,似乎建立了与 facebook 的初始通信。
Facebook.java 代码
package com.facebookContest.fb;
import com.visural.common.StringUtil;
public class Facebook {
// get these from your FB Dev App
private static final String api_key = "[MYKEY]";
private static final String secret = "MYSECRET";
private static final String client_id = "[MYKEY]";
// set this to your servlet URL for the authentication servlet/filter
private static final String redirect_uri = "http://[MYIP]:8080/facebookContest/app/index.do";
/// set this to the list of extended permissions you want
private static final String[] perms = new String[] {"publish_stream", "email"};
public static String getAPIKey() {
return api_key;
}
public static String getSecret() {
return secret;
}
public static String getLoginRedirectURL() {
return "http://graph.facebook.com/oauth/authorize?client_id=" +
client_id + "&display=page&redirect_uri=" +
redirect_uri+"&scope="+StringUtil.delimitObjectsToString(",", perms);
}
public static String getAuthURL(String authCode) {
return "http://graph.facebook.com/oauth/access_token?client_id=" +
client_id+"&redirect_uri=" +
redirect_uri+"&client_secret="+secret+"&code="+authCode;
}
}
FacebookUserService.java
package com.facebookContest.fb;
import java.net.URL;
import org.json.JSONObject;
import com.visural.common.IOUtil;
class FacebookUserService {
public void authFacebookLogin(String accessToken, int expires) {
try {
JSONObject resp = new JSONObject(
IOUtil.urlToString(new URL("https://graph.facebook.com/me?access_token=" + accessToken)));
String id = resp.getString("id");
String firstName = resp.getString("first_name");
String lastName = resp.getString("last_name");
String email = resp.getString("email");
// custom code
} catch (Throwable ex) {
throw new RuntimeException("failed login", ex);
}
}
}
我的过滤器类 FBOAuth.java 代码:
package com.facebookContest.fb;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import com.visural.common.StringUtil;
public class FBOAuth implements Filter {
@Autowired
FacebookUserService facebookUserService;
public void init(FilterConfig fc) throws ServletException {
}
public void doFilter(ServletRequest srvlReq, ServletResponse srvReq, FilterChain fc) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)srvlReq;
HttpServletResponse response = (HttpServletResponse)srvReq;
String code = srvlReq.getParameter("signed_request");
if (StringUtil.isNotBlankStr(code)) {
String authURL = Facebook.getAuthURL(code);
URL url = new URL(authURL);
try {
String result = readURL(url);
String accessToken = null;
Integer expires = null;
String[] pairs = result.split("&");
for (String pair : pairs) {
String[] kv = pair.split("=");
if (kv.length != 2) {
throw new RuntimeException("Unexpected auth response");
} else {
if (kv[0].equals("access_token")) {
accessToken = kv[1];
}
if (kv[0].equals("expires")) {
expires = Integer.valueOf(kv[1]);
}
}
}
if (accessToken != null && expires != null) {
facebookUserService.authFacebookLogin(accessToken, expires);
response.sendRedirect("http://[MYIP]:8080/facebookContest/app/index.do");
} else {
throw new RuntimeException("Access token and expires not found");
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
private String readURL(URL url) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream is = url.openStream();
int r;
while ((r = is.read()) != -1) {
baos.write(r);
}
return new String(baos.toByteArray());
}
public void destroy() {
}
}
在第 45 行
String result = readURL(url);
过滤器使用从调试器复制的以下网址进行获取 - 对我来说似乎正确 -
抛出的异常String result = readURL(url);
是这个
java.io.IOException: Server returned HTTP response code: 400 for URL: http://graph.facebook.com/oauth/access_token?client_id=[MYAPPID]&redirect_uri=http://[MYIP]:8080/facebookContest/app/index.do&client_secret=[MYAPPSECRET]&code=GdbObQHyYPvIKnkShMBv8Wry-UNPAQWAMmSVyXe5n_k.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MTM1ODUwNDQ4OCwicGFnZSI6eyJpZCI6IjM1NDcxOTMwNDYzNTQ4MSIsImxpa2VkIjpmYWxzZSwiYWRtaW4iOnRydWV9LCJ1c2VyIjp7ImNvdW50cnkiOiJnciIsImxvY2FsZSI6ImVsX0dSIiwiYWdlIjp7Im1pbiI6MjF9fX0
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1625)
at java.net.URL.openStream(URL.java:1037)
at com.facebookContest.fb.FBOAuth.readURL(FBOAuth.java:78)
at com.facebookContest.fb.FBOAuth.doFilter(FBOAuth.java:44)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Ιαν 18, 2013 12:21:30 ΜΜ org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [facebookContest] in context with path [/facebookContest] threw exception
java.lang.RuntimeException: java.io.IOException: Server returned HTTP response code: 400 for URL: http://graph.facebook.com/oauth/access_token?client_id=[MYAPPID]&redirect_uri=http://[MYIP]:8080/facebookContest/app/index.do&client_secret=[MYAPPSECRET]&code=GdbObQHyYPvIKnkShMBv8Wry-UNPAQWAMmSVyXe5n_k.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MTM1ODUwNDQ4OCwicGFnZSI6eyJpZCI6IjM1NDcxOTMwNDYzNTQ4MSIsImxpa2VkIjpmYWxzZSwiYWRtaW4iOnRydWV9LCJ1c2VyIjp7ImNvdW50cnkiOiJnciIsImxvY2FsZSI6ImVsX0dSIiwiYWdlIjp7Im1pbiI6MjF9fX0
at com.facebookContest.fb.FBOAuth.doFilter(FBOAuth.java:71)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Caused by: java.io.IOException: Server returned HTTP response code: 400 for URL: http://graph.facebook.com/oauth/access_token?client_id=[MYAPPID]&redirect_uri=http://[MYIP]:8080/facebookContest/app/index.do&client_secret=[MYAPPSECRET]&code=GdbObQHyYPvIKnkShMBv8Wry-UNPAQWAMmSVyXe5n_k.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MTM1ODUwNDQ4OCwicGFnZSI6eyJpZCI6IjM1NDcxOTMwNDYzNTQ4MSIsImxpa2VkIjpmYWxzZSwiYWRtaW4iOnRydWV9LCJ1c2VyIjp7ImNvdW50cnkiOiJnciIsImxvY2FsZSI6ImVsX0dSIiwiYWdlIjp7Im1pbiI6MjF9fX0
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1625)
at java.net.URL.openStream(URL.java:1037)
at com.facebookContest.fb.FBOAuth.readURL(FBOAuth.java:78)
at com.facebookContest.fb.FBOAuth.doFilter(FBOAuth.java:44)
... 16 more
我相信不需要我的 spring/hibernate 配置,因为应用程序似乎运行正常。如果有人需要它,尽管提供它没有问题。
我已经阅读了几篇表明redirect_uri 错误的帖子。我一遍又一遍地检查它,但事实并非如此。应用程序选项卡安装在页面上,其中包含我在引发异常时调用的确切 uri。
尝试获取访问令牌时,我也无法在此处找到答案 HTTP 400 错误
请随时指导我了解任何可能有帮助的文档。
非常感谢!