繁体   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