我正在构建一个使用 Angular 和 Express 进行身份验证的简单登录页面。我有以下内容:
- 登录组件
- 使用接收到的 jwt 令牌进行 http 调用并设置本地存储的服务
- 注册页面的路由守卫
我的警卫正在工作,如果没有令牌,它会阻止访问“/注册”路由。因为第一次登录没有令牌,并且当调用登录组件的 onSubmit() 时,守卫似乎在设置令牌之前检查,我必须触发 onSubmit() 两次 - 一次获取密钥,然后另一个登录。我希望能够在输入正确的凭据后立即登录。
我该如何解决这个问题?提前致谢!
登录组件.ts
...
this.loginForm = this.fb.group({
username: ['', Validators.required],
password: ['', Validators.required]
})
...
onSubmit() {
const formValue = this.loginForm.value;
if (formValue.username && formValue.password) {
this.authService.login(formValue.username, formValue.password)
.subscribe(
resp => { console.log(resp); },
err => { console.log(err); }
)
this.router.navigateByUrl('/registration');
}
}
身份验证服务.service.ts:
export class AuthSerivce {
constructor(private http: HttpClient) {}
login(username: string, password: string) {
const body = {
username: username,
password: password
}
return this.http.post<AuthResp>(ROUTES.login, body)
.pipe(
tap(res => this.setSession(res)),
catchError(this.handleError),
shareReplay()
)
}
...
private setSession(authResp: AuthResp) {
const expiresAt = moment().add(authResp.expiresIn, 'second');
localStorage.setItem('id_token', authResp.token);
localStorage.setItem("expires_at", JSON.stringify(expiresAt.valueOf()));
}
public isLoggedIn() {
return moment().isBefore(this.getExpiration());
}
public getExpiration() {
const expiration = localStorage.getItem("expires_at");
const expiresAt = JSON.parse(expiration);
return moment(expiresAt);
}
}
auth.guard.ts
export class AuthGuard implements CanActivate {
constructor(
private _authService: AuthService,
private _router: Router) { }
canActivate(): boolean {
if (this._authService.isLoggedIn()) {
return true;
} else {
this._router.navigate(['login']);
return false;
}
}
}