用户切换帐户时 Facebook 身份验证出现问题
我在我的 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 : "");
}
}
I'm having an issue with authenticating facebook users via oauth 2.0 in my java web app. The problem seems to happen when a user that's using my app logs out of their facebook account and logs back into another facebook account. Then when I attempt to authenticate the new facebook account, facebook responds with a 400 error. If the user then switches back the first account, then facebook will authenticate them just fine.
I think the problem is that when I request a code from facebook, it returns the same code for both users, but the second user can't get an access token with that code because the code was made for the first user.
Does anyone know how I can fix this? Here is a stripped down version of my code. Note, I have an interceptor that automatically redirects users to FacebookDirectorAction if the page requires them to be signed in. So FacebookDirectorAction handles getting a code, and access token, and finally redirecting the user back to the original page they requested.
@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 : "");
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论