【问题标题】:Can't get user information on route navigation无法获取有关路线导航的用户信息
【发布时间】:2018-12-25 14:19:44
【问题描述】:

我为我的 Angular 应用程序创建了一个服务,如下所示:

export class AuthService {

    public currentUser: Subject<firebase.User> = new Subject();
    public currentUserId: Subject<string> = new Subject();

    constructor(private auth: AngularFireAuth){
        auth.authState.subscribe(r => {
            this.currentUser.next(r);        // the user object
            this.currentUserId.next(r.uid);  // the user id
        });
    }
}

发生路由时,我在组件中使用此服务。

当用户第一次从他们的浏览器到达一个页面时,其他组件会成功地收到身份验证更改的通知。但是,当用户单击链接转到另一个页面时,这两个 observable 不会触发,并且侦听组件不会收到身份验证状态更改的通知。唯一的工作方法是如果用户刷新他们的浏览器,因为他们似乎只在用户登陆他们的第一页时才会触发。之后,我丢失了用户信息,再也没有收到通知。

如何在每次发生页面导航时触发两个可观察对象?或者这甚至是正确的方法吗?

【问题讨论】:

  • 当前用户是否经常更改,这就是为什么需要通知?否则,似乎一个简单的属性就足够了?
  • 不,它非常稳定。如果我做一个属性,那么检索用户信息会很复杂,因为我必须先检查属性,如果它是null,那么订阅Subejcts。对每个组件都这样做很烦人。
  • 你看过这里的例子吗:angularfirebase.com/lessons/…

标签: angular firebase firebase-authentication rxjs angularfire2


【解决方案1】:

不知道路由时使用的原因...我在上一个项目中使用了CanLoad

//Inside Auth Service
public authStates = new BehaviorSubject<AuthState>(this.getAuthState());

private getAuthState(): AuthState {
  const token = this.getToken();
  if (token || !tokenHelper.isTokenExpired(token)) {
    const payload: JwtPayload = jwt(token);
    return {
      authenticated: true,
      id: payload.uid,
      role: payload.type
    };
  }
  return {
    authenticated: false
  };
}

canLoad(route: Route): Observable<boolean> {
  const roles: string[] = route.data.roles;
  return this.authState.pipe(
    take(1),
    map((authState: AuthState) => {
      if (
        authState.authenticated &&
        authState.role &&
        roles.includes(authState.role)
      ) {
        return true;
      } else if (!authState.authenticated && roles.includes("guest")) {
        return true;
      }
      this.toastrService.error(
        "You have not sufficient permissions for that action"
      );
      return false;
    })
  );
}

// In routes module
const appRoutes: Routes = [
  {
    path: environment.settings.user.backendPath,
    loadChildren: "app/user/user.module#UserModule",
    canLoad: [AuthService],
    data: {
      roles: ["user"]
    }
  },
]

我还使用了 canActivate、canActivateChild 和自定义编写的 auth 指令,例如 *hideForRoles、*showForRoles、authOnly 等...

【讨论】:

    【解决方案2】:

    感谢@DeborahK 到 angularfirebase.com 的链接,这就是解决方案:

    export class AuthService {
        public currentUser: Observable<UserDoc>;
    
        constructor(
            public afAuth: AngularFireAuth
        ) {
            this.currentUser = this.afAuth.authState;
    
            // then other components subscribe to this observable
            // and can run `.id` on the resolved parameter.
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多