Firebase Auth Custom声称不会传播到客户端

时间:2017-12-31 13:39:16

标签: android firebase firebase-authentication

我有一个UID 1的用户,其中自定义声明设置为,

<div id="wrapper">
  <div class="first">
    <div id="content_1">content_1</div>
    <div id="content_2">content_2</div>
    <div id="content_3">content_3</div>
  </div>
  <div id="content_4">content_4</div>
</div>

我通过以下方式从ADMIN SDK for java为此用户设置新的自定义声明:

frompos=true

我在服务器端打印声明以检查声明是否已设置:

Map<String,Object> claims = new HashMap<>();

claims.put("frompos",false);

FirebaseAuth.getInstance().setCustomUserClaimsAsync("1", claims).get(10000,
                        TimeUnit.MILLISECONDS);

预期的结果是声明设置:

UserRecord user = FirebaseAuth.getInstance().getUserAsync("1").get(10000,
                        TimeUnit.MILLISECONDS);

LOG.debug("user new claims " + user.getCustomClaims());

现在在android sdk方面,我让用户已经登录,所以我手动刷新ID令牌以传播声明,就像文档说的那样 (https://firebase.google.com/docs/auth/admin/custom-claims

user new claims {frompos=false}

现在我使用此处打印的打印Id令牌并在服务器端验证并打印声明

FirebaseAuth.getInstance().getCurrentUser().getIdToken(true).addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
         @Override
         public void onComplete(@NonNull Task<GetTokenResult> task) {
                    if(task.isSuccessful()){
                    Log.d("FragmentCreate","Success refreshing token "+(FirebaseAuth.getInstance().getCurrentUser()==null));

                    Log.d("FragmentCreate","New token "+task.getResult().getToken());

                        }
                    }
         }).addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Log.d("FragmentCreate","Failure refreshing token "+(FirebaseAuth.getInstance().getCurrentUser()==null)+" "+e.toString());
                    }
         });

但这里印刷的声明是:

 FirebaseToken tokenTest = FirebaseAuth.getInstance(ahmedabadRepoApp).verifyIdTokenAsync(token).get(10000,TimeUnit.MILLISECONDS);

 LOG.debug("Token claims are "+tokenTest.getClaims());

因此即使我手动刷新了Id令牌,frompos值也没有传播到客户端sdk。

3 个答案:

答案 0 :(得分:2)

我在角度问题上遇到了同样的问题 - 我在服务器上使用Admin SDK设置声明,但之后它们不会在客户端的用户身上。

使用以下内容我可以看到有效载荷中的声明:

pip install --install-option="--prefix=PATH_TO_YOUR_VIRTUAL_ENV_DIR/lib/PYTHON_VERSION" PyMySQL

以下是我复制上述内容的good write up

  

目前,客户端代码必须解析并解码用户的ID   令牌以提取嵌入其中的声明。在将来,   Firebase客户端SDK可能会为此用途提供更简单的API   情况下。

来自Firebase Docs的相关信息:

  

只能通过用户的ID令牌检索自定义声明。   可能需要访问这些声明来修改客户端UI   在用户的角色或访问级别上。但是,后端访问应该   验证后,始终通过ID令牌强制执行   解析其主张。自定义声明不应直接发送给   后端,因为它们不能在令牌之外被信任。

     

一旦最新的声明传播到用户的ID令牌,您就可以   通过首先检索ID令牌然后解析它来获取这些声明   有效载荷(base64已解码):

  this.firebaseAuth.auth.currentUser.getIdToken().then(idToken => {

    const payload = JSON.parse(this.b64DecodeUnicode(idToken.split('.')[1]))

    console.log(payload);
    }

  )

b64DecodeUnicode(str) {
    return decodeURIComponent(atob(str).replace(/(.)/g, function (m, p) {
        var code = p.charCodeAt(0).toString(16).toUpperCase();
        if (code.length < 2) {
            code = '0' + code;
        }
        return '%' + code;
    }));
  }

答案 1 :(得分:1)

这可能会有所帮助:https://stackoverflow.com/a/38284384/9797228

firebase.auth().currentUser.getIdToken(true)

答案 2 :(得分:0)

客户端SDK正在缓存旧令牌(旧声明)。

您应该添加一种机制来更改声明(例如,推送通知)后刷新它,或者只是等待旧令牌过期或用户拖出并再次登录。

在这里https://youtu.be/3hj_r_N0qMs?t=719

进行了说明

修改

您可以使用firebase.auth().currentUser.getIdToken(true)强制sdk刷新令牌