-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" ローカルを返すことを確認済みです。次の URL を使用して、作成したテスト facebook ページにこのアプリケーションを追加しました: http://www.facebook.com/dialog/pagetab?app_id=[MYAPPID]&next=http://[MYIP]:8080/facebookContest/ app/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);

フィルターは、デバッガーからコピーされた次の URL で get を実行します - 私には正しいようです -

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 に答える