簡體   English   中英

登錄用戶初始值為null Angular 7

[英]Logged in user initial value is null Angular 7

我有一個帶有表單和此功能的登錄組件來執行登錄

this.auth.login(this.f.email.value, this.f.password.value)
        .pipe(first())
        .subscribe(
            data => {
                this.router.navigate([this.returnUrl])
            },
            error => {
                this.serverError = error;
                this.loading = false;
            });

this.auth是我的身份驗證服務,如下所示

private currentUserSubject: BehaviorSubject<User>
public currentUser: Observable<User>

constructor(private http: HttpClient) {
    this.currentUserSubject = new BehaviorSubject<User>(JSON.parse(localStorage.getItem('currentUser')))
    this.currentUser = this.currentUserSubject.asObservable()
}

public get currentUserValue(): User {
    return this.currentUserSubject.value
}

login(email: string, password: string) {
    console.log('making login request')
    return this.http.post<any>(`${Config.apiUrl}/login`, { email, password })
        .pipe(map(user => {
            // login successful if there's a jwt token in the response
            if (user && user.token) {
                // store user details and jwt token in local storage to keep user logged in between page refreshes
                localStorage.setItem('currentUser', JSON.stringify(user))
                this.currentUserSubject.next(user)
            }

            return user
        }))
}

它向我的node.js后端發出請求,如果信用證正確則返回用戶。 然后,angular將AuthorizationServicelocalStoragecurrentUserSubject的值設置為服務器返回的用戶值。 這一切都正在發揮作用(我假設)。

在我的登錄組件從授權服務獲取數據后,它會嘗試將用戶路由到auth.guard保護頁面。 這就是我的路線。

{
    path: 'user',
    component: UserComponent,
    canActivate: [AuthGuard]
}

我的AuthGuard看起來像這樣

constructor(
    private router: Router,
    private authenticationService: AuthenticationService
) { }

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    const currentUser = this.authenticationService.currentUserValue

    if (currentUser) {
        // check if route is restricted by role
        if (route.data.roles && route.data.roles.indexOf(currentUser.role) === -1) {
            // role not authorised so redirect to home page

            this.router.navigate(['/'])
            return false
        }

        // authorised so return true
        return true
    }

    // not logged in so redirect to login page with the return url
    this.router.navigate(['/login'], { queryParams: { redirect: state.url } })
    return false
}

在AuthGuard canActivate()函數中, currentUser在初始登錄請求后始終為null。 所以它將我重定向回我的登錄頁面。

我無法弄清楚為什么它是空的。 奇怪的是,在我提交登錄表單並重定向回登錄頁面之后,如果我刷新瀏覽器,則currentUser值不再為null,並且應用程序的行為與我打算行為一樣。 有沒有我缺少或正在做的事情我不應該做那件事造成的?

這是我提交登錄表單時所經歷的過程和值的圖像 在此輸入圖像描述

解決方案最終比將BehaviorSubject更改為Subject更簡單。 在我的登錄組件中,我在組件提供程序中有這樣的AuthenticationService。

@Component({
  selector: 'login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css'],
  providers: [AuthenticationService]
})

我所要做的就是從使用它的所有組件中刪除提供程序中的服務,這樣最終會看起來像這樣。

@Component({
  selector: 'login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})

讓我感到驚訝的是這個鏈接上的問題解決方案。 https://github.com/angular/angular/issues/11618

為了使兩個組件在多個組件之間共享服務,您應該提供更高級別的服務,而不是將服務添加到兩個組件的提供者。

兩次注冊任何提供程序將創建兩個獨立實例。

因此,為了使用AuthorizationService並維護登錄用戶的狀態,我必須將其從組件提供程序中刪除。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM