-2

我正在尝试设置原型环境并与 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);

过滤器使用从调试器复制的以下网址进行获取 - 对我来说似乎正确 -

http://graph.facebook.com/oauth/access_token?client_id=[MYAPPID]&redirect_uri=http://[MYIP]:8080/facebookContest/app/index.do&client_secret=[MYAPPSECRET]&code=s0PmZHCK9Vl2tBzIGLDJbJJ4uiVUTIkU2KiknGboLrI.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MTM1ODUwNDY0NiwicGFnZSI6eyJpZCI6IjM1NDcxOTMwNDYzNTQ4MSIsImxpa2VkIjpmYWxzZSwiYWRtaW4iOnRydWV9LCJ1c2VyIjp7ImNvdW50cnkiOiJnciIsImxvY2FsZSI6ImVsX0dSIiwiYWdlIjp7Im1pbiI6MjF9fX0

抛出的异常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 错误

请随时指导我了解任何可能有帮助的文档。

非常感谢!

4

1 回答 1

1

我设法解决了这个问题,所以我想我可以分享解决方案,如果其他人遇到这个问题。

异常的错误消息带有包含更多信息的 json 响应。要查看响应,您只需将构建的 url 粘贴到任何浏览器即可。我这样做如下所示。



    public static String getAuthURL(String authCode) {
            return "https://graph.facebook.com/oauth/access_token?"+
                    "client_id=" + client_id +
                    "&redirect_uri=" + redirect_uri + 
                    "&client_secret=" + secret + 
                    "&code=" + authCode;
        }

将显示错误消息。并将为您提供有关出了什么问题的信息。就我而言,我正在尝试通过 http 进行授权 GET,并且错误消息指示此类操作应通过 https 完成。

我纠正了这个问题,我终于得到了 access_token。

于 2013-01-21T09:31:01.927 回答