已解决
我正在Angular中实现用户状态:isLogged true / false。
因此,无论我在哪里,都将验证用户是否已登录以显示或隐藏内容。 为此,我不希望仅控制accessToken是否在localstorage中,但我会使用authService来检查它是否要求服务器(带有Http请求)。因此,我希望authService中的isLogged()可以让我返回true / false或设置一个布尔值true / false。通常,我在Component的.subscribe中处理“ res”和“ err”,但我不会在每个组件中都重复。问题是我不知道如何直接在服务中使用.subscribe。
那时候我正在使用此解决方案。它可以用,但我一点都不喜欢!!
isLogged() {
return this.http
.get<any>(this.isLoggedUrl)
.pipe(catchError(this.errorHandler));
}
// I call this method in each component that needs to know if user is logged
isLoggedResHandle() {
this.isLogged().subscribe(
(res) => {
if (res.status == 200) {
this.loggedIn = true;
}
},
(err) => {
if (err.error.message == 'TokenExpiredError') {
this.loggedIn = false;
//DO.. try refresh token. if refreshed: this.loggedIn = true
} else {
// for any other errors:
this.loggedIn = false;
}
}
);
}
解决方案
auth.service.ts
isLogged() {
const accessToken = this.getAccessToken;
if (typeof accessToken === 'undefined' || accessToken === null) {
console.log('pieroooooooooo');
this.loggedIn = false;
return;
}
return this.http
.get<any>(this.isLoggedUrl)
.pipe(catchError(this.errorHandler))
.subscribe(
(res) => {
if (res.status == 200) {
this.loggedIn = true;
}
},
(err) => {
if (err.error.message == 'TokenExpiredError') {
const refreshToken = this.getRefreshToken;
if (typeof refreshToken !== 'undefined' || refreshToken !== null) {
this.loggedIn = false;
}
this.loggedIn = false;
// TODO: try to refresh it
} else {
this.loggedIn = false;
}
}
);
}
getIsLogged() {
return this.loggedIn;
}
header.component.ts或我想要的任何组件,例如:
<button class="btn btn-light my-2 my-sm-0" id="cartBtn" *ngIf="authService.getIsLogged()" [routerLink]="'/profile'"
type="submit">
<i class="fas fa-shopping-cart"></i>
Mio Profilo
</button>
app.component.ts // //在刷新后也保持“用户状态”更新:
export class AppComponent implements OnInit {
constructor(private authService: AuthService) {}
ngOnInit(): void {
this.authService.isLogged();
}
}
答案 0 :(得分:0)
解决方案可以是实现ParentComponentClass
逻辑的isLoggedResHandle
,需要它的每个Component都可以扩展该类。
class ParentWithIsLoggedLogicCompoent {
loggedIn = false
constructor(private isLogged: IsLoggedService) {}
isLoggedResHandle() {
this.isLogged().subscribe(
isLogged => this.loggedIn = isLogged,
error => this.loggedIn = false
)
}
}
class YourOtherComponent extends ParentWithIsLoggedLogicCompoent implements OnInit {
ngOnInit() {
this.isLoggedResHandle();
}
}
您可以使用retryWhen
运算符将重试逻辑提取到服务中。我不确定语法是否正确,但是会是这样:
isLogged() {
return this.http
.get<any>(this.isLoggedUrl)
.pipe(
retryWhen(errors => {
errors.switchMap(error => {
if(errors.error.message != 'TokenExpiredError') {
throw errors
}
//DO.. try refresh token. if refreshed: this.loggedIn = true
})
}),
catchError(this.errorHandler)
);
}