1

我在我的 java web 应用程序中通过 oauth 2.0 对 facebook 用户进行身份验证时遇到问题。当使用我的应用程序的用户注销他们的 Facebook 帐户并重新登录到另一个 Facebook 帐户时,问题似乎就会发生。然后,当我尝试验证新的 facebook 帐户时,facebook 以 400 错误响应。如果用户随后切换回第一个帐户,那么 facebook 将对他们进行身份验证。

我认为问题在于,当我从 facebook 请求代码时,它为两个用户返回相同的代码,但第二个用户无法使用该代码获得访问令牌,因为代码是为第一个用户制作的。

有谁知道我该如何解决这个问题?这是我的代码的精简版本。请注意,如果页面要求用户登录,我有一个拦截器会自动将用户重定向到 FacebookDirectorAction。因此 FacebookDirectorAction 处理获取代码和访问令牌,最后将用户重定向回他们请求的原始页面。

@UrlBinding("/facebookdirector/{destination}/{destinationParameter}")
public class FacebookDirectorAction extends BaseActionBean {

    private static final String BASE_REDIRECT_URI = "http://apps.facebook.com/lawlessdev/facebookdirector";
    private static final String APP_ID = "My app id";
    private static final String APP_SECRET = "My secret";

    public static final String AUTH_VIEW = VIEW_PATH + "auth.jsp";

    private String destination;
    private String destinationParameter;
    private String code;
    private String access_token;
    private String authUrl;

    @DefaultHandler
    public Resolution direct() throws IOException, FacebookException, ServletException {
        if (access_token == null && code == null) {
            return authorize();
        }
        else if (access_token == null) {
            retrieveAccessToken();
        }
        // If access_token is still null then we may mave a bad code.  Redirect to an insecure page.
        if (access_token == null) {
            return new RedirectResolution(CategoriesAction.class);
        }

        RedirectResolution redirectResolution = new RedirectResolution("/" + destination + (destinationParameter != null ? "/" + destinationParameter : ""));
        redirectResolution.addParameter("access_token", access_token);
        return redirectResolution;
    }

    public Resolution authorize() throws IOException, ServletException {
        authUrl = "https://graph.facebook.com/oauth/authorize?client_id=" + APP_ID + "&redirect_uri=" + getRedirectUri();
        return new ForwardResolution(AUTH_VIEW);
    }

    public void retrieveAccessToken() throws UnsupportedEncodingException {
        try {
            URL accessTokenURL = new URL("https://graph.facebook.com/oauth/access_token?client_id=" + APP_ID + "&client_secret=" + APP_SECRET + "&code=" + code + "&redirect_uri=" + getRedirectUri());
            URLConnection accessTokenURLConnection = accessTokenURL.openConnection();
            accessTokenURLConnection.connect();
            BufferedReader in = new BufferedReader(
                                new InputStreamReader(
                                accessTokenURLConnection.getInputStream()));
            String inputLine;

            while ((inputLine = in.readLine()) != null) {
                ParameterParser parameterParser = new ParameterParser();
                List<NameValuePair> nameValuePairs = parameterParser.parse(inputLine, '&');
                for (NameValuePair nameValuePair : nameValuePairs) {
                    if (nameValuePair.getName().equals("access_token")) {
                        access_token = nameValuePair.getValue();
                    }
                }
            }
            in.close();

        } catch (MalformedURLException e) {     // new URL() failed
        } catch (IOException e) {               // openConnection() failed
        }
    }

    private String getRedirectUri() throws UnsupportedEncodingException {
        return BASE_REDIRECT_URI + "/" + destination + (destinationParameter != null ? "/" + destinationParameter : "");
    }
}
4

0 回答 0