验证访问令牌时出错:用户尚未授权应用程序。脸书 SDK 4

Posted

技术标签:

【中文标题】验证访问令牌时出错:用户尚未授权应用程序。脸书 SDK 4【英文标题】:Error validating access token: The user has not authorized application. Facebook SDK 4 【发布时间】:2015-04-23 11:27:54 【问题描述】:

情况是这样的:

如果我之前通过

向我的应用授予了读取权限
LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("email"));

然后,当我需要分享时,我通过以下方式请求发布权限:

LoginManager.getInstance().logInWithPublishPermissions(getActivity(), Arrays.asList("publish_actions"));

一切正常,直到我在 Web 中删除我的应用程序的权限。

如果应用程序被杀死或停止并且我需要共享,我将检查我是否仍然拥有权限:

if(userAuthorizedMyApp())
    LoginManager.getInstance().logInWithPublishPermissions(this, Arrays.asList("publish_actions"));
 else 
    LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("email"));

方法 userAuthorizedMyApp() 返回 false(accessToken null):

private boolean userAuthorizedMyApp() 
    boolean authorized;
    AccessToken accessToken = AccessToken.getCurrentAccessToken();
    if(DEBUG) Log.v(TAG, "accessToken [" + accessToken +"]");

    if(accessToken != null)
        Set<String> currentPermissions = accessToken.getPermissions();
        authorized = currentPermissions.contains("public_profile");
     else 
        authorized = false;
    
    if(DEBUG) Log.v(TAG, "userAuthorizedMyApp[" + authorized +"]");

    return authorized;

我尝试像第一次一样进行常规登录:

LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("email"));

我收到了:

public void onError(FacebookException error)

onError, error HttpStatus: -1, errorCode: 190, errorType: null, errorMessage: 验证访问令牌时出错:用户尚未授权应用程序123456789123456。

任何想法我做错了什么?

【问题讨论】:

当你得到这个错误时,你可以尝试清除访问令牌LoginManager.logout(),然后重新登录吗? 实际上,通过第二次执行相同的操作,一切正常 - 登录屏幕已打开。但是第一次尝试出错会让用户感到困惑。 请记住,访问令牌缓存在客户端上,因此除非您实际发出请求,否则无法验证它是否仍然有效。这里发生的情况是,在失败的情况下,您正在调用 loginWithPublishPermissions (本质上是对额外权限的请求,当您已经拥有令牌时),这会失败,因为用户已删除该应用程序。第二次(成功案例),你调用 loginWithRead,这被视为一个全新的 auth 请求,它成功了。 【参考方案1】:

只需执行以下操作:

@Override
public void onError(FacebookException error) 
    Timber.e(error, "Error during facebook login");
    AccessToken.setCurrentAccessToken(null);
    LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("email"))

【讨论】:

抱歉回复晚了:我想自定义这条消息。 drive.google.com/open?id=0B7xjlHVL47MbWVVKY1JSbWJGdk0 您无法自定义该消息 那么,我们不能隐藏它并使用其他消息代替吗? 您可以 - 将应用程序从开发模式切换到生产模式。【参考方案2】:

致电AccessToken.refreshCurrentAccessTokenAsync() 对我有用。我在调用FacebookCallback.onError() 时遇到错误 AccessToken.refreshCurrentAccessTokenAsync() 清除 Facebook SDK 中的访问令牌。

因为这是一个异步调用,我不能立即调用loginManager.logInWithReadPermissions();没有回调,所以我向用户显示AlertDialog,当用户单击“确定”时,我调用loginManager.logInWithReadPermissions()

所以用户体验并不算太差,对于边缘情况来说是可以接受的。

【讨论】:

【参考方案3】:

要进行正确的验证,请检查访问令牌是否为空或过期:

  AccessToken accessToken = AccessToken.getCurrentAccessToken();
  boolean isLoggedIn = accessToken != null && !accessToken.isExpired();
     
  if (isLoggedIn)  
      //Post Facebook.
   else 
      manager.logIn(shareAct, Arrays.asList("public_profile"));
  

【讨论】:

以上是关于验证访问令牌时出错:用户尚未授权应用程序。脸书 SDK 4的主要内容,如果未能解决你的问题,请参考以下文章

Facebook SDK 3.1 - 验证访问令牌时出错

Spotify API - 在授权过程中检索访问令牌时出错

尝试在 spotipy 中获取访问令牌时授权码无效

AADSTS70002:验证凭据时出错。 AADSTS50126:用户名或密码无效

使用 Passport 和 Laravel 进行身份验证时返回访问令牌和用户

Spotify API 身份验证不使用访问令牌重定向