1

我正在构建一个使用 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;
    }
  }
}
4

1 回答 1

0

解决了这个问题。我需要将导航放在登录调用的订阅中:

登录组件.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);
              this.router.navigateByUrl('/registration'); 
          },
          err => { console.log(err); }
        )
    }
  }
于 2019-03-20T11:20:28.970 回答