首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Angular OpenId连接:在token准备就绪之前进行第一次渲染

Angular OpenId连接:在token准备就绪之前进行第一次渲染
EN

Stack Overflow用户
提问于 2021-05-03 17:59:10
回答 2查看 302关注 0票数 0

我使用的是Angular 10和angular-auth-oidc-client (https://github.com/damienbod/angular-auth-oidc-client)。

如果没有登录,我希望用户被重定向到认证服务器(无登录按钮)。

我这样做了:

代码语言:javascript
复制
// component : 

export class AppComponent implements OnInit {

  constructor(public authService: AuthService) {
  }

  async ngOnInit(): Promise<void> {
    return this.authService.checkAuthAndLogin();
  }
}


// service : 

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  async checkAuthAndLogin(): Promise<void> {
    await this.oidcSecurityService.checkAuth().subscribe((auth) => {
      if (!auth) {
        this.login();
      }
      console.log('is authenticated', auth);
    });
  }

}

// http client interceptor to send tokens to my backend : 

@Injectable()
export class TokenInterceptor implements HttpInterceptor {
  constructor(
    private oidcSecurityService: OidcSecurityService
  ) {
  }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    request = request.clone({
      setHeaders: {
        Authorization: `Bearer ${this.oidcSecurityService.getToken()}`
      }
    });
    return next.handle(request);
  }
}

它正在工作,但第一次渲染总是失败,我必须刷新页面才能让它工作。它在第一次加载时向我的后端服务器发送一个空令牌。

我发现了一个变通方法,那就是在init方法中等待500毫秒,但它看起来很脏:

代码语言:javascript
复制
export class AppComponent implements OnInit {

  constructor(public authService: AuthService) {
  }

  loggedIn = false;

  async ngOnInit(): Promise<void> {
    return this.authService.checkAuthAndLogin().then(() => {
      
      return new Promise(resolve => setTimeout(resolve, 500)).then(() => {
        this.loggedIn = true;
      });
    });
  }
}

在我的应用组件模板中:

代码语言:javascript
复制
 <div *ngIf="loggedIn">
  [...]
 </div>

它的行为就像oidcSecurityService.checkAuth()解析为early,而令牌还没有准备好。

有没有更干净的解决方案?

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-05-03 19:59:17

我删除了服务中的async/await (编辑:和gnInit中的async ),保留了带有ng-if的isLogged布尔值(仍然不知道我需要做什么),现在它可以工作了:

代码语言:javascript
复制
checkAuthAndLogin(): Observable<void> {
    return this.oidcSecurityService.checkAuth().pipe(map((auth) => {
      if (!auth) {
        this.login();
      }
      console.log('is authenticated', auth);
    }));
  }

// componenent : 
ngOnInit(): Promise<void> {
    return this.authService.checkAuthAndLogin().toPromise().then(() => {
      this.loggedIn = true;
    });
  }
票数 0
EN

Stack Overflow用户

发布于 2021-05-03 18:14:10

我认为您没有返回正确的结果:

代码语言:javascript
复制
 checkAuthAndLogin(): Promise<string> {
 return new Promise((res, rej) => {
   this.oidcSecurityService.checkAuth().subscribe((auth) => { // don't user await with observables
      if (!auth) {
        this.login();
        rej('Auth is failed')
      }
      console.log('is authenticated', auth);
      if (auth) res('authenticated');
    });
 })
    
  }

似乎当你调用checkAuthAndLogin的时候,你没有返回任何东西。我不确定你的身份验证服务在一起做什么。但您需要等待身份验证令牌接收,然后使其登录为真并解析promise,或者您可以使用行为主题来实现它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67366952

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档