我用角度实现了auth保护,但我没有访问本地存储或cookie来检查用户是否经过身份验证,而是有一个API端点,如果存在一个仅包含附加到请求的JWT的httponly cookie,则返回200 OK,否则将返回401 Unauthorized。
这是我尝试过的
// auth.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root',
})
export class AuthService {
constructor(
private httpClient: HttpClient,
) {}
login(username: string, password: string) {
return this.httpClient.post('/users/login', { username, password });
}
isLoggedIn(): boolean {
this.httpClient.get('/users/check').subscribe({
next: (data) => {
return true;
},
error: () => {
return false;
},
});
return false;
}
}// auth.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { AuthService } from './auth.service';
@Injectable({
providedIn: 'root',
})
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(): boolean {
if (!this.authService.isLoggedIn()) {
this.router.navigate(['login']);
return false;
}
return true;
}
}// app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LoginComponent } from './login/login.component';
import { LayoutComponent } from './layout/layout.component';
import { ProjectsComponent } from './projects/projects.component';
import { AuthGuard } from './core/auth/auth.guard';
const routes: Routes = [
{
path: '',
component: LayoutComponent,
canActivate: [AuthGuard],
children: [{ path: 'projects', component: ProjectsComponent }],
},
{ path: 'login', component: LoginComponent },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule {}问题发生在用户登录和身份验证cookie设置之后,isLoggedIn()函数仍然返回false,从而将用户重定向回登录页面。我的猜测是,这与我错误地处理来自httpclient的可观察到的内容有关,并在请求完成之前将其发送给return false;?
任何帮助都是感激和感谢的,提前!
发布于 2022-07-06 03:30:35
这是一个经典的异步处理问题,以及一些功能范围的理解.
当您这样做时,可以看到两个主要问题:
isLoggedIn(): boolean {
this.httpClient.get('/users/check').subscribe({
next: (data) => {
return true; // issue 02
},
error: () => {
return false; // issue 02
},
});
return false; // issue 01
}false,因为这是isLoggedIn函数作用域中唯一的返回语句。(经典异步问题)return的i属于订阅回调的范围,而不是isLoggedIn函数的范围.。
要解决这一问题:
isLoggedIn() {
return this.httpClient.get('/users/check').pipe(
map(() => true),
catchError(() => of(false))
)
}。
canActivate() {
return this.authService.isLoggedIn().pipe(take(1), tap(loggedIn => {
if (!loggedIn) this.router.navigate(['login']);
}));
}发布于 2022-07-06 06:11:03
试试这个,它对我有用。
在isLoggedIn函数中:
isLoggedIn(): boolean {
return this.httpClient.get('/users/check').subscribe({
next: (data) => {
return true;
},
error: () => {
return false;
},
});
}内部canActivate警卫:
canActivate(){
return this.authService.isLoggedIn().subscribe(res => {
if (!res) this.router.navigate(['login']);
else return true;
});
}https://stackoverflow.com/questions/72877427
复制相似问题