Android Session.isOpened()==true,但Session.getAccessToken()==”&引用;

Android Session.isOpened()==true,但Session.getAccessToken()==”&引用;,android,facebook,android-facebook,Android,Facebook,Android Facebook,在我的应用程序中,我试图通过将Facebook会话信息(令牌和过期日期)传递到我的服务器来进行身份验证(登录) 我对应用服务器的登录顺序如下: 获取活跃的facebook会话 如果会话有效,则获取令牌并将其发送到服务器 在代码中: Session session = Session.getActiveSession(); if(session != null && session.isOpened() && !didLogin) { didLogin =

在我的应用程序中,我试图通过将Facebook会话信息(令牌和过期日期)传递到我的服务器来进行身份验证(登录)

我对应用服务器的登录顺序如下:

  • 获取活跃的facebook会话
  • 如果会话有效,则获取令牌并将其发送到服务器
  • 在代码中:

    Session session = Session.getActiveSession();
    if(session != null && session.isOpened() && !didLogin) {
        didLogin = true;
        String token = session.getAccessToken();
        Date expires = session.getExpirationDate();
        loginWithFacebookSession(token, expires);
    }
    
    我突然注意到,经过几个月的正常工作后,发送到服务器的信息偶尔无效,特别是
    令牌
    是一个空字符串,
    过期
    是一个无效日期

    在浏览了一下Facebook SDK(3.0.1版)之后,我发现了我的错误可能的基础:

    private static final Date MIN_DATE = new Date(Long.MIN_VALUE);
    private static final Date ALREADY_EXPIRED_EXPIRATION_TIME = MIN_DATE;
    private static final Date DEFAULT_LAST_REFRESH_TIME = new Date();
    
    static AccessToken createEmptyToken(List<String> permissions) {
        return new AccessToken("", ALREADY_EXPIRED_EXPIRATION_TIME, permissions, AccessTokenSource.NONE,
                DEFAULT_LAST_REFRESH_TIME);
    }
    
    private static final Date MIN_Date=新日期(Long.MIN_值);
    私有静态最终日期已\u过期\u过期\u时间=最小\u日期;
    私有静态最终日期默认值\上次\刷新\时间=新日期();
    静态AccessToken createEmptyToken(列出权限){
    返回新的AccessToken(“),已过期\u过期\u时间,权限,AccessTokenSource.NONE,
    默认值(上次刷新时间);
    }
    
    这意味着Facebook SDK正在创建一个空令牌,并返回一个
    SessionState.Category.OPENED\u Category

    为什么
    session.isOpened()
    返回
    true
    而实际上没有
    accessToken
    信息?我应该检查另一处房产吗?这是Facebook SDK中的一个bug吗


    编辑:
    向Facebook报告此问题:

    我解决了问题。问题出在密钥散列中

    遵循本教程

    转至步骤4运行样品

    最后,您将找到疑难解答部分,这就是解决方案


    谢谢

    除了Facebook SDK就像巫毒魔法,还有一些你正在做的事情我在我的授权流中没有做。这里我假设您的代码片段不在Session.StatusCallback函数中。无论如何,我总是在从回调访问令牌之前打开会话进行读取。这个请求只是在返回前使用加载微调器给用户带来几毫秒的不便。当用户从Facebook设置页面中删除权限时,它也会有所帮助

    我的身份验证流如下所示:

    private void startFbAuth() {
        Session session = Session.getActiveSession();
        if (session == null) {
            session = new Session(getApplicationContext());
            Session.setActiveSession(session);
    
            Session.OpenRequest openReadRequest = new Session.OpenRequest(this);
            openReadRequest.setPermissions(Arrays.asList({ "email" }));
            openReadRequest.setCallback(statusCallback);
    
            Session.NewPermissionsRequest permissionReadRequest = new Session.NewPermissionsRequest(this, Arrays.asList(EMAIL_PERMISSIONS));
            permissionReadRequest.setCallback(statusCallback);
    
            if (!session.isOpened() && !session.isClosed()) {
                session.openForRead(openReadRequest);
            } else {
                session.requestNewReadPermissions(permissionReadRequest);
            }
        }
    
        private Session.StatusCallback statusCallback = new SessionStatusCallback();
    
        private class SessionStatusCallback implements Session.StatusCallback {
            @Override
            public void call(Session session, SessionState state, Exception exception) {
                if (session.isClosed()) {
                    session.closeAndClearTokenInformation();
                    Session.setActiveSession(null);
                    SessionStore.clearFacebookInformation(Activity.this);
                    // Either throw an error or try reconnecting by calling startFbAuth
                }
                if (exception != null) {
                    session.closeAndClearTokenInformation();
                    Session.setActiveSession(session);
                    // Either throw an error or try reconnecting by calling startFbAuth
                } else {
                    if (session.isOpened()) {
                        String token = session.getAccessToken();
                        // It shouldn't be null or empty here
                    }
                }
            }
        }
    

    使用此方法并检查哈希是否正确

    public void getHashKeyForFacebook(Activity activity, String packageName){
        try{
            PackageInfo info = activity.getPackageManager().getPackageInfo(packageName,  PackageManager.GET_SIGNATURES);
    
            for (Signature signature : info.signatures){
                    MessageDigest md = MessageDigest.getInstance("SHA");
                    md.update(signature.toByteArray());
                    Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
            }
        } catch (Exception ex){
    
        }
    }
    

    如何打开会话/设置活动会话?我正在使用文档中的
    UiLifecycleHelper
    类。可能您必须检查会话是否处于打开的\u令牌\u更新状态,即令牌已更改,但会话仍处于打开状态。欢迎使用FacebookSDK…我将会话设置为null,在后台运行本机fb应用程序时。问题是什么?它与哈希键无关。应用程序很好,它是电话,应用程序是SDK。密钥散列是正确的,这不能回答这个问题,但其他的,如果会话不是空的,比如op的情况。。。我不明白这个代码示例的意思。。。