【问题标题】:Implementing isLoggedIn() function in Angular with oidc-client in *ngIf在 *ngIf 中使用 oidc-client 在 Angular 中实现 isLoggedIn() 函数
【发布时间】:2019-11-10 16:56:15
【问题描述】:

目标:我正在尝试使用 IdentityServer4 和 oidc 客户端在 Angular 应用程序中隐藏和显示登录和注销按钮。

问题:我的 isLoggedIn 函数的响应在返回 true 之前返回 undifined,并且 *ngIf 从不显示注销按钮或隐藏登录按钮。见代码:

app.componenet.html:

<span>
      <button *ngIf="!isLoggedIn()" mat-button (click)="login()">Login</button>
      <button *ngIf="isLoggedIn()" mat-button (click)="logout()">Logout</button>
</span>

app.componenet.ts:

    isLoggedIn(){
        console.log('isLoggedIn -this._authService.isLoggedIn():',
          this._authService.isLoggedIn());
        this._authService.isLoggedIn();
      }

auth.service.ts

isLoggedIn(): boolean{
    return this._user && this._user.access_token && !this._user.expired;
  }

在 auth.service.ts 我这样设置用户对象:

 this._userManager = new UserManager(config);
    this._userManager.getUser().then(user =>{
      if(user && !user.expired){
        this._user = user;
      }

console.log 输出:

我尝试过的:

  1. 我尝试使用我的 oidc-client 版本,切换 在最低版本和 1.4.1 之间,并确保它们匹配 package.json 和我的 oidc-login-redirect.html 文件。
  2. 将 auth.service.ts isLoggedIn 函数转换为 promise isLoggedIn() 并使用异步管道直接从 *nfIf 调用它

auth.service.ts 承诺{ 返回新的承诺(解决 => { 解决(this._user && this._user.access_token && !this._user.expired); }); }

app.component.html

  <button *ngIf="!this._authService.isLoggedIn() | async" mat-button (click)="login()">Login</button>
  <button *ngIf="this._authService.isLoggedIn() | async" mat-button (click)="logout()">Logout</button>

这些事情都没有奏效,并且承诺尝试导致谷歌浏览器挂断:

【问题讨论】:

  • 我认为您没有包含足够的代码来解决这个问题。没有理由必须将您的代码包装在一个 Promise 中或使用 async。由于设置了this._user,因此必须发生延迟。这是有道理的,因为在 oidc_client 中你必须调用 manager.getUser() 来返回一个承诺。所以有多种状态,unknownloggedinloggedout。请务必考虑到这一点。
  • @DanielGimenez 我添加了设置 this._user 的代码,如果您对缺少的内容有任何建议,请告诉我。
  • 我希望 authService 持有一个 Behavior Subject 等,并在用户登录时发出一个值。这将使您的组件中的所有内容都更加清晰,其中设置了局部变量在ngOnInit 上,您的模板将仅基于该局部变量

标签: javascript angular identityserver4 openid-connect


【解决方案1】:

如果您在 Angular 应用程序中的某个地方调用 signinRedirectCallback(而不是位于 SPA 之外的单独 html 页面),则您的代码设置 this.user 很可能在调用登录回调之前被调用。

您应该在 UserManager 上订阅 addUserLoaded 并在您的身份验证服务中从该处理程序中设置用户。这样您的用户将始终保持最新状态。

如果上面的代码是从您的源代码复制/粘贴的,那么您的 app.component isLoggedIn 不会从身份验证服务返回值,它只是在身份验证服务上调用 isLoggedIn,但不会返回值。

【讨论】:

  • 感谢您的帮助。我确实在单独的文件中有 signinRedirectCallback 。问题是由于我只是忘记返回值:(。在愚蠢的一天工作、让孩子上床睡觉、只睡几个小时和喝太多咖啡后编写代码并不是一个好主意。谢谢。
猜你喜欢
  • 1970-01-01
  • 2018-10-01
  • 2020-12-07
  • 2019-12-27
  • 1970-01-01
  • 1970-01-01
  • 2019-03-25
  • 2020-03-03
  • 2020-12-19
相关资源
最近更新 更多