代码之家  ›  专栏  ›  技术社区  ›  BigDevJames

角度应用卡在无限循环中

  •  0
  • BigDevJames  · 技术社区  · 6 年前

    我有一个Angular Web应用程序,它使用@microsoft/microsoft graph client获取登录用户的信息。@azure/msal angular用于登录用户。我有一个身份验证服务,它用这个登录用户:

      async signIn(): Promise<void> {
        const result = await this.msalService.loginPopup(OAuthSettings.consentScopes)
          .catch((reason) => {
            this.alertsService.add('Login failed', JSON.stringify(reason, null, 2));
          });
    
        if (result) {
          this.authenticated = true;
          await this.getUser();
        }
      }
      private async getClient(): Promise<Client> {
        const graphClient = Client.init({
          // Initialize the Graph client with an auth
          // provider that requests the token from the
          // auth service
          authProvider: async (done) => {
            const token = await this.getAccessToken()
              .catch((reason) => {
                done(reason, null);
              });
            if (token) {
              done(null, token);
            } else {
              done('Could not get an access token', null);
            }
          }
        });
        return graphClient;
      }
    
    private async getUser() {
        if (!this.authenticated) {
          return null;
        }
        const graphClient = await this.getClient();
    
        // Get the user from Graph (GET /me)
        const graphUser = await graphClient.api('/me').get();
    
        console.log('USERNAME: ', graphUser.displayName);
        sessionStorage.setItem('d365dataportal.user', graphUser);
        if (graphUser.mail != null) {
          sessionStorage.setItem('d365dataportal.user.email', graphUser.mail);
        } else {
          sessionStorage.setItem('d365dataportal.user.email', graphUser.userPrincipalName);
        }
        sessionStorage.setItem('d365dataportal.user.avatar', graphUser.avatar);
        sessionStorage.setItem('d365dataportal.user.name', graphUser.displayName);
      }
    

    我的OAuthSettings如下所示:

    export const OAuthSettings = {
      appId: 'App GUID from Azure Here',
      redirectUri: 'http://localhost:4200',
      consentScopes: ['user.read',
        'Directory.Read.All',
        'Directory.ReadWrite.All',
        'Directory.AccessAsUser.All']
    };
    

    我遇到的问题是,当调用此.msalService.loginPopup()时,整个应用程序挂起,弹出窗口从不关闭,并且似乎从不进行身份验证并重定向回我的页面。我不知道为什么会这样。有人能看到任何明显的错误吗?

    编辑

    我离开上面的内容是因为这是我最初的问题。我意识到这个问题与我原来的头衔无关,于是改了问题的名字。

    2 回复  |  直到 6 年前
        1
  •  0
  •   BigDevJames    6 年前

    我解决了我的问题,它与使用Azure广告或图形API无关。在我的组件HTML中,我有一个查找函数结果的*ngif。看起来像这样:

    <a mat-list-item *ngIf="authService.functionThatReturnsBoolean()" [routerLink]="['/SomeRoute']" routerLinkActive="router-link-active">Link Name</a>
    

    相反,我更改了我的服务,将结果填充到服务中的一个属性中,并将*ngif指向该属性,如下所示:

    <a mat-list-item *ngIf="authService.booleanProperty" [routerLink]="['/SomeRoute']" routerLinkActive="router-link-active">Link Name</a>
    

    这个问题与Angular继续在*ngif中寻找状态的方式有关。然后它被卡在一个似乎是无穷无尽的循环,直到铬崩溃。

        2
  •  0
  •   kivikall    6 年前

    我做了一些调试,我认为有一个bug或者是我在MSAL中不理解的特性。如果您查看msal库中的useragentapplication.js,这里有一个名为 loginPopupHelper();

    我认为问题就在那里。如果你看看 this.authorityInstance.ResolveEndpointsAsync() 成功的回调函数如果块

    if (popUpWindow) {
        _this._logger.infoPii("Navigated Popup window to:" + urlNavigate);
        popUpWindow.location.href = urlNavigate;
    }
    

    很明显,它将弹出窗口重定向到重定向URL。它永远不会像失败回调那样关闭弹出窗口。我的快速和肮脏的修复方法是像这样修改它

    if (popUpWindow) {
        _this._logger.infoPii("Navigated Popup window to:" + urlNavigate);
        window.location.href = urlNavigate;
        popUpWindow.close();
    }
    

    不言而喻,这不是一个稳定的解决方案,因为每当你更新这个库时,我想它都会被覆盖。此外,这不再触发弹出窗口,而是重定向到MS登录页,然后在提供凭据时返回。我知道为什么会这样,但现在没有时间。我想我会在Github开始讨论这个问题,如果还没有在那里讨论过的话。

    但是,是的,这就是我能找到的。

    编辑:实际上在GitHub中已经有一些与此相关的东西了。例如

    https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/545

    https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/479

    推荐文章