在服务器端流上请求长期访问令牌

时间:2012-04-24 13:57:56

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

我有一个Java网络应用程序,它将项目发布到我们的用户Facebook墙上,当用户最初注册时,我们得到60天access_token,这是持久存储到我们的数据库,现在我删除了offline_access我使用'登录当用户登录我们的网站时,facebook'按钮更新令牌,这一切都很好,因为他们通常会间隔60天以上访问。

我已经实现了上述功能并且运行良好...但后来我发现登录操作生成的访问令牌在1小时后过期....显然不太好我们不能发布到他们的墙上他们不在了。

下面的代码演示了我们如何通过signed_request方法获取令牌(在Java SEAM应用程序中),这样可行,但令牌是短暂的

任何人都可以建议如何确保令牌为60天类型

由于

public void loginWithFacebook(){
    accessToken = null;
    try {
        accessToken = FaceBookSecurity.getFBAccessToken();
    } catch (Exception e) {
        log.error("Error getting FB access token: "+e);
    }
    FacebookClient facebookClient = new DefaultFacebookClient(accessToken);
    com.restfb.types.User facebookUser = facebookClient.fetchObject("me", com.restfb.types.User.class);
    facebookEmail = facebookUser.getEmail();
    if (facebookEmail != null) {
        new RunAsOperation(true) {
            public void execute() {
                user = ((UserDAO)Component.getInstance("userDAO")).findByEmail(StringUtils.lowerCase(facebookEmail));
                if (user != null && user.getFacebookToken() != null && !accessToken.equals(user.getFacebookToken())) {
                    user.setFacebookToken(accessToken);
                    log.error("FB: updating "+user.getFirstname()+" "+user.getSurname()+"s FB token to: "+accessToken);
                }
            }
        }.run();
        if (user != null) {
            //set the user as logged in

            return;
        }
    }
    messagePoster.postPopupErrorMessage(messages.get("facebookLoginFailed"));
}

public static String getFBAccessToken()
        throws Exception {

    HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
    Cookie fbCookie = getFBCookie(request);

    String fbCookieValue = fbCookie.getValue();
    String[] stringArgs = fbCookieValue.split("\\.");
    String encodedPayload = stringArgs[1];
    JsonObject data;
    try{
        String payload = base64UrlDecode(encodedPayload);

        // gets the js object from the cookie
        data = new JsonObject(payload);
    }catch (Exception e){
        return "";
    }

    String authUrl = getAuthURL(data.getString("code"));
    URL url = new URL(authUrl);
    URI uri = new URI(url.getProtocol(), url.getHost(), url.getPath(),
            url.getQuery(), null);
    String result = readURL(uri.toURL());

    String[] resultSplited = result.split("&");
    return resultSplited[0].split("=")[1];
}

// creates the url for calling to oauth.
public static String getAuthURL(String authCode) {
    String url = "https://graph.facebook.com/oauth/access_token?client_id="
            + FacebookApp.appId
            + "&redirect_uri=&client_secret="
            + FacebookApp.appSecret + "&code="
            + authCode;
    return url;
}

// reads the url.
private static String readURL(URL url) throws IOException {
    InputStream is = url.openStream();
    InputStreamReader inStreamReader = new InputStreamReader(is);
    BufferedReader reader = new BufferedReader(inStreamReader);
    String s = "";
    int r;
    while ((r = is.read()) != -1) {
        s = reader.readLine();
    }
    reader.close();
    return s;
}

private static String base64UrlDecode(String input){
    return new String(Base64.decodeBase64(input.getBytes()));
}

1 个答案:

答案 0 :(得分:1)

如果您只需要发布到用户的墙上,那么您还可以使用 app_access_token ,前提是您要求 publish_stream 权限。

您可以致电:

https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID
&client_secret=YOUR_APP_SECRET
&grant_type=client_credentials

Read this

编辑:app access_tokens在重置应用密码之前不会过期。