基于Firebase用户角色的Angular 2 Route Guard可以激活 [英] Angular 2 Route Guard CanActivate based on Firebase User Role

查看:386
本文介绍了基于Firebase用户角色的Angular 2 Route Guard可以激活的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经花了几个小时在圈子里工作,试图解决这个问题。我需要根据用户角色来确保路由。

 构造函数(private AF:AngularFire,private db:AngularFireDatabase,私有路由器:Router,private auth:AngularFireAuth){

af.auth.subscribe(user => {

if(user){
this.getUserRole(user);
} else {
console.log('no user');
}

});





$ b $ p $这个至少得到了这个角色: b
$ b

  getUserRole(user):any {

this.db.list('users',{
query :{
orderByKey:true,
equalTo:user.uid
}
})。subscribe(user => console.log(user [0] .role));




$ p
$ b

如果这个用户是在CanActivate的基础上登录,但显然这个角色没有关系。

pre $ code canActivate(route:ActivatedRouteSnapshot,
state:RouterStateSnapshot):可观察到的与LT;布尔> {

return this.af.auth.take(1)
.map(authSate => !! authSate)
.do(authenticated => {
console.log(authenticated)
if(!authenticated)
this.router.navigate(['/ login'])
})

}

我无法弄清楚如何将用户角色考虑在内。我的设置是非常基本的...它/用户/ $ uid /角色。



以下是我尝试过的其他内容:

导出类AuthService {

  static UNKNOWN_USER = new AuthInfo(null,null); 

authInfo $:BehaviorSubject< AuthInfo> = new BehaviorSubject< AuthInfo>(AuthService.UNKNOWN_USER);

构造函数(private AF:AngularFire,private db:AngularFireDatabase,私有路由器:Router,private auth:AngularFireAuth){

af.auth.subscribe(user => {

if(user){

let getRole = this.db.list('users',{
query:{
orderByKey:true,
equalTo:user.uid
}
})。subscribe(snap => {
if(snap.length === 0){
return;
} else {
let role =;
role = snap [0] .role
const authInfo = new AuthInfo(user.uid,role);
this .authInfo $ .next(authInfo);
}
});

} else {
console.log('no user');
}

});




以下是AuthInfo类:



导出类AuthInfo {$ /

$ $ p $ 构造函数(public $ uid:string,public role:string) {}

isLoggedIn(){
console.log('from authinfo',!! this。$ uid)
//告诉我们用户是否登录
return !! this。$ uid;


isGroupALoggedIn(){
//告诉我们用户是否登录
return !! this。$ uid&& this.role ===GroupA;


isGroupBLoggedIn(){
//告诉我们用户是否登录
return !! this。$ uid&& this.role ===GroupB;

code










$ b $ p


$ b

这是一个来自Home组件的测试:

导出类HomeComponent implements OnInit {

  authInfo:AuthInfo 

构造函数(private authService:AuthService){}
$ b ngOnInit(){
//返回boolean
this。 authService.authInfo $ .subscribe(authInfo => {
console.log(authInfo);
this.authInfo = authInfo
});

code










$ b $ p


$ b

这工作,但我不知道如何将此与CanActivate绑定

解决方案

您需要链接两个observables - 获取用户和获得用户角色的人 - 使用 mergeMap()运算符。



这个代码在一个 canActivate 钩子中。


$ b

  canActivate():Observable< boolean> {
return af.auth
.mergeMap(user =>
//如果用户存在,则从userData中提取角色,如果没有用户,则为空字符串
user?getUserRole用户).map(userData => userData [0] .role):Observable.of('')

//将角色转换为真或假
//因为这canActivate()必须返回。
.map({
if(userRole ===GroupA){
return true;
} else {
this.router.navigate(['/登录']);
}
});





$ b在这个例子中,对于角色为GroupA的用户, 。
$ b $ p更新:根据dhndeveloper的要求,检查用户是否存在用户+重定向(如果没有允许的角色)。

I've been spending hours and hours working in circles trying to figure this out. I need to secure the routes based on the users roles.

constructor(private af: AngularFire, private db: AngularFireDatabase, private router: Router, private auth: AngularFireAuth) {

    af.auth.subscribe(user => {

        if (user) {
            this.getUserRole(user);
        } else {
            console.log('no user');
        }

    });

}

This at least gets the role:

 getUserRole(user): any {

  this.db.list('users', {
        query: {
            orderByKey: true,
            equalTo: user.uid
        }
    }).subscribe(user => console.log(user[0].role));

}

This at is a working CanActivate based on if this user is logged in but obviously the role doesn't matter.

canActivate(route:ActivatedRouteSnapshot,
            state:RouterStateSnapshot):Observable<boolean> {

            return this.af.auth.take(1)
        .map(authSate => !!authSate)
        .do( authenticated => {
            console.log(authenticated)
            if (!authenticated)
            this.router.navigate(['/login'])
        })

}

I can't figure out how to take the user role in to account. My setup is very basic... Its /users/$uid/role.

Here is something else I tried:

export class AuthService {

static UNKNOWN_USER = new AuthInfo(null, null);

authInfo$: BehaviorSubject<AuthInfo> = new BehaviorSubject<AuthInfo>(AuthService.UNKNOWN_USER);

constructor(private af: AngularFire, private db: AngularFireDatabase, private router: Router, private auth: AngularFireAuth) {

    af.auth.subscribe(user => {

        if (user) {

            let getRole = this.db.list('users', {
                query: {
                    orderByKey: true,
                    equalTo: user.uid
                }
            }).subscribe(snap => {
                if (snap.length === 0) {
                    return;
                } else {
                    let role = "";
                    role = snap[0].role
                    const authInfo = new AuthInfo(user.uid, role);
                    this.authInfo$.next(authInfo);
                }
            });

        } else {
            console.log('no user');
        }

    });

}

Here is the AuthInfo class:

export class AuthInfo {

constructor(public $uid: string, public role: string) { }

isLoggedIn() {
    console.log('from authinfo', !!this.$uid)
    //tells us if user is logged in or not
    return !!this.$uid;
}

isGroupALoggedIn() {
    //tells us if user is logged in or not
    return !!this.$uid && this.role === "GroupA";
}

isGroupBLoggedIn() {
    //tells us if user is logged in or not
    return !!this.$uid && this.role === "GroupB";
}

}

This is a test from the Home Component:

export class HomeComponent implements OnInit {

authInfo: AuthInfo

constructor(private authService: AuthService) { }

ngOnInit() {
    //returns boolean
    this.authService.authInfo$.subscribe(authInfo => {
        console.log(authInfo);
        this.authInfo = authInfo
    });
}

}

This works as well but I can't figure out how to tie this to CanActivate

解决方案

You need to chain the two observables — the one getting the user and the one getting the user role — using the mergeMap() operator.

Place all this code inside a canActivate hook.

canActivate(): Observable<boolean> {
  return af.auth
    .mergeMap(user =>
      // Extract the role from userData if user exists, or empty string if no user.
      user ? getUserRole(user).map(userData => userData[0].role) : Observable.of('')
    )
    // Transform the role into true or false
    // since this is what canActivate() must return.
    .map({
      if (userRole === "GroupA") {
        return true;
      } else {
        this.router.navigate(['/login']);
      }
    });
}

In this example, the route will be activated for users with role "GroupA".

UPDATE: Check for existence of user + redirect if no allowed role, as per dhndeveloper requirements.

这篇关于基于Firebase用户角色的Angular 2 Route Guard可以激活的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆