我使用的是Angular 10和angular-auth-oidc-client (https://github.com/damienbod/angular-auth-oidc-client)。
如果没有登录,我希望用户被重定向到认证服务器(无登录按钮)。
我这样做了:
// 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毫秒,但它看起来很脏:
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;
});
});
}
}在我的应用组件模板中:
<div *ngIf="loggedIn">
[...]
</div>它的行为就像oidcSecurityService.checkAuth()解析为early,而令牌还没有准备好。
有没有更干净的解决方案?
谢谢
发布于 2021-05-03 19:59:17
我删除了服务中的async/await (编辑:和gnInit中的async ),保留了带有ng-if的isLogged布尔值(仍然不知道我需要做什么),现在它可以工作了:
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;
});
}发布于 2021-05-03 18:14:10
我认为您没有返回正确的结果:
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,或者您可以使用行为主题来实现它。
https://stackoverflow.com/questions/67366952
复制相似问题