AngularFire getIdToken(true) 不刷新令牌

AngularFire getIdToken(true) not refreshing token

我有一个 angularfire 身份验证服务,它工作得很好——除了它不会刷新令牌。

我的刷新代码:

firebase.auth().currentUser.getIdToken(true).then((token: string) => {
    const newUser = { token: token }; // new user details in brief
    this.user.next(newUser);
});

可以很好地调用 firebase 服务并给出响应,但它仅 returns 当前令牌并且不会刷新令牌 - 因此它仍会在 1 小时后退出应用程序。

我已经阅读了很多有关 getIdToken 的问题,但 none 专门针对不刷新的令牌。

我做了一个 stackblitz:https://stackblitz.com/edit/angular-ivy-uvcdz7?file=src/app/app.component.ts 所以你可以看到完整的代码(虽然它因为某些原因不起作用,但也因为我不知道如何通过 SB 将项目连接到 firebase )

编辑

为了帮助解决一些我不期望的其他奇怪行为,例如在我的 ngOnInit 中我有...

this.fAuth.onAuthStateChanged((state) => {
    console.log(state);
})

当我登录或注销时它什么都不做 - 没有消息表明状态已经改变。 None 我希望在身份验证发生变化时触发的这些功能似乎可以执行任何操作。

编辑 2

作为补充信息,在我添加赏金之前,我对 Angular 和 AngularFire 进行了全面而痛苦的更新,所以现在 Angular 是 v13 和 Angular Fire是7.2.0,看看这会不会有什么不同,但是没有,getIdToken仍然没有提供token的刷新。

编辑 3

所以这个函数是作为下面的答案提供的:

public getToken$(): Observable<firebase.auth.IdTokenResult> {
    return from(this.fAuth.currentUser).pipe(switchMap(user => {
        return from(user.getIdTokenResult(true)).pipe(map(token => {
            console.log(token);
            return token;
        }));
    }));
}

哪个returns一个用户对象:

{ “索赔”:{ "name": "波哥米普", “图片”:“图片”, “管理员”:是的, "iss": "https://securetoken.google.com/repo", “aud”:“回购”, “auth_time”:1638464159, "user_id": "用户编号", “子”:“用户ID”, “我”:1638464323, “exp”:1638467923, "电子邮件": "电子邮件@gmail.com", “email_verified”:正确, “火力基地”:{ “身份”:{ “电子邮件”: [ “电子邮件@gmail.com” ] }, "sign_in_provider": "密码" } }, “令牌”:“这是令牌”, "authTime": "2021 年 12 月 2 日星期四 16:55:59 GMT", "issuedAtTime": "2021 年 12 月 2 日星期四 16:58:43 GMT", "expirationTime": "2021 年 12 月 2 日星期四 17:58:43 GMT", "signInProvider": "密码", “signInSecondFactor”:空 }

这是在该函数中记录的 'token',但此 (token.token) 中的令牌是刷新 ID 还是实际令牌?因为它没有改变,但如果它是刷新令牌,那将是有意义的......我们是否能看到实际的令牌?

Firebase 处理令牌刷新过程,因此无需手动刷新令牌。可以从 'authState' 属性.

中读取 Firebase 身份验证状态

@Injectable({
  providedIn: 'root',
})
export class AuthenticationService implements OnInit {

  public readonly userId$: Observable<string>;

  public readonly profile$: Observable<MyProfile>;


  constructor(
    public firestore: AngularFirestore,
    public fAuth: AngularFireAuth,
    private router: Router,
  ) {

    this.userId$ = this.fAuth.authState.pipe(
      map(fbUser => fbUser ? fbUser.uid : null),
      distinctUntilChanged(),
      tap(uid => {
        console.log('AuthService: userId$', uid);
      }),
      shareReplay(1),
    );


    this.profile$ = this.authService.userId$.pipe(
      switchMap(authId => {
        if (authId) {
          return this.getById(authId);
        } else {
          return EMPTY;
        }
      }),
      tap(profile => {
        console.log('[AuthService] profile$', profile);
      }),
      shareReplay(1),
    );
  }

  public getById(id: string): Observable<MyProfile> {
    return this.firestore.doc<MyProfile>('users/'+id).get();
  }

}

您可以通过这种方式使用 Observables 强制刷新令牌:

public getToken$(): Observable<firebase.auth.IdTokenResult> {
  return from(this.angularFireAuth.currentUser).pipe(switchMap(user => {
    return from(user.getIdTokenResult(true)).pipe(map(token => {
      return token;
    }));
  }));
}