【问题标题】:How do I authenticate with facebook serverside without using the JS library如何在不使用 JS 库的情况下通过 facebook 服务器端进行身份验证
【发布时间】:2013-10-25 08:28:40
【问题描述】:

在我的网站上,允许用户使用 facebook 登录。这样做时,我请求许可 发布到用户提要。这就像一个魅力。

登录后,允许用户撰写评论,并在保存评论时询问用户是否要将评论发布到 Facebook 上的用户源。由于应该在将评论保存在我的本地数据库中之后发布到 facebook,我知道我需要执行身份验证服务器端,然后当我有一个令牌时,我可以发布到例如。

http://graph.facebook.com/10XXXX40308/feed 

message : "This works"

我一直在尝试按照here 的描述实现 facebook 网络登录:

步骤如下:

  1. 针对
    https://graph.facebook.com/oauth/authorize?client_id=MY_API_KEY&执行请求
    redirect_uri=http://www.facebook.com/connect/login_success.html&
    scope=publish_stream
  2. Facebook 会将您重定向到 http://www.facebook.com/connect/login_success.html? 代码=MY_VERIFICATION_CODE
  3. 请求 https://graph.facebook.com/oauth/access_token?client_id=MY_API_KEY& 重定向uri=http://www.facebook.com/connect/login_success.html& client_secret=MY_APP_SECRET&code=MY_VERIFICATION_CODE Facebook 将 回复 access_token=MY_ACCESS_TOKEN

在浏览器中执行 1. 时,应用程序会相应地运行。我使用 MY_VERIFICATION_CODE 从 facebook 获得重定向:

所以我尝试用这样的代码来做:

        String url = "https://graph.facebook.com/oauth/authorize?client_id="+clientId+"&scope=publish_stream&redirect_uri=http://www.facebook.com/connect/login_success.html";

        URL obj = new URL(url);
        conn = (HttpURLConnection) obj.openConnection();
        conn.setReadTimeout(5000);
        conn.setRequestMethod("GET");

        System.out.println("Request URL ... " + url);

        boolean redirect = false;

        // normally, 3xx is redirect
        int status = conn.getResponseCode();
        if (status != HttpURLConnection.HTTP_OK) {
            if (status == HttpURLConnection.HTTP_MOVED_TEMP
                    || status == HttpURLConnection.HTTP_MOVED_PERM
                    || status == HttpURLConnection.HTTP_SEE_OTHER)
                redirect = true;
        }

        System.out.println("Response Code ... " + status);

        if (redirect) {

            // get redirect url from "location" header field
            String newUrl = conn.getHeaderField("Location");

            // get the cookie if need, for login
            String cookies = conn.getHeaderField("Set-Cookie");

            // open the new connnection again
            conn = (HttpURLConnection) new URL(newUrl).openConnection();
            conn.setRequestProperty("Cookie", cookies);                

            System.out.println("Redirect to URL : " + newUrl);

        }

        BufferedReader in = new BufferedReader(
                new InputStreamReader(conn.getInputStream()));
        String inputLine;
        StringBuffer html = new StringBuffer();

        while ((inputLine = in.readLine()) != null) {
            html.append(inputLine);
        }
        in.close();

        System.out.println("URL Content... \n" + html.toString());
        System.out.println("Done");

但是发生的情况是,我没有返回 302,而是返回了 200 和登录 代码中的页面:

好像漏了一步,或者看不懂流程。

我想要完成的是实现类似于 janrain 的类似调用:

https://rpxnow.com/api/v2/facebook/stream.publish

您可以在哪里这样做。

谢谢!

【问题讨论】:

    标签: java facebook-graph-api facebook-opengraph


    【解决方案1】:

    我猜 rtfm 在这里就位。用户需要进行身份验证,所以我在这里真正想做的是绕过身份验证过程。这当然是不允许的。所以 你怎么解决这个问题?

    当用户进行身份验证时,我需要保存访问令牌和过期时间,以便 我可以稍后将其添加到请求中。

    我认为这是唯一的方法...如果我错了,请纠正我。

    所以在身份验证过程中我创建了一个正则表达式:

    Pattern pattern = Pattern.compile("access_token=([a-zA-Z0-9]+)&expires=([0-9]+)"); 
    

    然后在来自 facebook 的回调中,我使用正则表达式提取令牌:

        String accessToken = "";
        String expires = "";
    
        Matcher matcher = pattern.matcher(token.trim());
        if(matcher.matches()) {
            accessToken = matcher.group(1);
            expires = matcher.group(2);
        } else {
            return new JSONObject()
                    .put("error", "OathBean: accessToken is null");
        }
    

    然后我调用 facebook 来获取用户的值并返回所有值以便我可以使用它们:

    return new JSONObject()
                    .put("facebookId", facebookId)
                    .put("firstName", firstName)
                    .put("lastName", lastName)
                    .put("email", email)
                    .put("photo", photo)
                    .put("accessToken", accessToken)
                    .put("expires", expires);
    

    稍后当用户想要在 facebook 上发表评论时。我填写请求并发布评论。

                Map<String, String> requestData = new HashMap<String, String>();
                requestData.put("link",url(newReview));                
                requestData.put("description", "reviewText");
                requestData.put("access_token", credential.getPassword());
                String query = createQuery(requestData);
                JSONObject result = null;
                try {
                    URL url = new URL("https://graph.facebook.com/"+identifier+"/feed");
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                    conn.setRequestMethod("POST");
                    conn.setDoOutput(true);
    
                    conn.connect();
                    OutputStreamWriter osw = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
                    osw.write(query);
                    osw.close();
    
                    result =  new JSONObject(IOUtils.toString(conn.getInputStream()));
                }
                catch (Exception    e) {
                    log.error("Could not call graph feed to publish for id: "+identifier, e);
                }
    
                if(result != null) {
                    boolean success = StringUtils.isNotBlank(result.getString("id"));
                    entityManager.persist(new FBPublishEvent(currentUser, newReview, success, result.toString()));                    
                }
    

    如果你有更好的解决方案,请分享=)

    【讨论】:

      猜你喜欢
      • 2017-03-03
      • 1970-01-01
      • 2020-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-19
      相关资源
      最近更新 更多