我有一个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。
答案 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刷新令牌