我在java网络应用中通过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 : "");
}
}