针对Facebook的客户端身份验证

时间:2012-07-31 16:12:39

标签: java facebook-graph-api authentication controller facebook-access-token

我们有一个带有弹簧mvc控制器的弹簧网络应用程序。它应该连接到我们的Facebook应用程序,以获取用于进一步访问的身份验证令牌。与我们的应用程序的通信似乎工作。当我点击链接时

<a href="https://www.facebook.com/dialog/oauth?client_id=something&redirect_uri=http://our.domaine.register/postback?user_id=12345&scope=manage_pages&response_type=code">connect</a>

它会将我重定向到Facebook,我会输入我的凭据并重定向回

our.domaine.register/postback?user_id=12345&code=SoMEcOde

这又是我们的Spring MVC控制器之一,但这并不重要,因为

问题是,facebook返回的代码是格式错误的accessToken

意思是如果我尝试使用它来访问受保护的资源,它将无法工作。使用通过图形API资源管理器检索的访问令牌替换相同的调用,它可以正常工作。

返回的代码有一种特殊的格式,其中包含“ - ”,“_”和“=”字符,而普通访问令牌从不具有这些字符。

所以我假设必须进行某种转换?!还是某种形成问题?

返回令牌:

AQBoXkcR5zRUiuHoO_lLdQfnxxxxxxxxxxxxxxxxoPPvZQTeybT9ebsI2SD1Xk

代码与accessToken相同吗?

官方文档主要是讨论使用锚点哈希(REDIRECT_URL /#access_token = ...)并通过javascript访问access_token,虽然我不知道为什么我想要这样做它不自然而且不可测试。 ..

是否有人使用code参数将其映射为请求参数,以便可以在控制器中访问它?

2 个答案:

答案 0 :(得分:2)

看起来你的response_type要求代码,这就是没有令牌返回的原因。

请检查https://developers.facebook.com/docs/authentication/

的最后一部分

正确呼叫的示例;

https://www.facebook.com/dialog/oauth?
    client_id=YOUR_APP_ID
   &redirect_uri=https://www.facebook.com/connect/login_success.html
   &response_type=token

当登录成功时,重定向ur包含access_token和expires_in params追加。 你可以解码网址参数来获得你需要的东西。 这是Android OAuth example的示例函数(易于适应java):

public static Bundle decodeUrl(String s) {
        Bundle params = new Bundle();
        if (s != null) {
            String array[] = s.split("&");
            for (String parameter : array) {
                String v[] = parameter.split("=");
                // YG: in case param has no value
                if (v.length==2){
                    params.putString(URLDecoder.decode(v[0]),
                                 URLDecoder.decode(v[1]));
                }
                else {
                    params.putString(URLDecoder.decode(v[0])," ");
                }
            }
        }
        return params;
    }

    /**
     * Parse a URL query and fragment parameters into a key-value bundle.
     * 
     * @param url the URL to parse
     * @return a dictionary bundle of keys and values
     */
    public static Bundle parseUrl(String url) {

        try {
            URL u = new URL(url);
            Bundle b = decodeUrl(u.getQuery());
            b.putAll(decodeUrl(u.getRef()));
            return b;
        } catch (MalformedURLException e) {
            Log.w(TAG, "parseUrl ex ->" + e.toString());
            return new Bundle();
        }
    }

答案 1 :(得分:1)

他们返回给您的代码是OAuth授权代码,没有访问令牌。您必须与另一个呼叫交换那个访问令牌。请参阅Facebook的documentation for server-side authentication

中的第4点

<强>更新 (对不起,错过标题,你说“客户端身份验证”;))

使用response_type=token代替response_type=code,因此您可以直接获取访问令牌,而不是OAuth授权代码。请参阅Facebook documentation for client-side authentication上的没有JS SDK的客户端身份验证部分。

<强>更新

在尝试开发Web应用程序时,server-side authentication flow是正确使用的。这意味着将授权代码(重定向用户后获得的代码)与另一个呼叫交换访问令牌。

因此,如果我现在理解正确,那么您的问题就是如何从您收到的响应中获取访问令牌。使用Spring检查this example如何执行此类操作。对于您的情况,这可能是获取授权码:

@RequestMapping(value = "/postback", params = "code", method = RequestMethod.GET)
@ResponseBody
private void accessCode(@RequestParam("code") String code,
                            HttpServletRequest request,
                            HttpServletResponse response) throws Exception {
        //Now the variable 'code' holds the authorization code
}