【问题标题】:Angular 6 authentication guardAngular 6 身份验证防护
【发布时间】:2018-08-18 18:21:46
【问题描述】:

我遵循了一个关于在我的应用程序上使用假后端设置 JWT 身份验证的教程,但我遇到了身份验证问题。事实上,我只是想访问一个客户端面板或一个具有两个不同角色的“管理员”面板,管理员角色是“客户”和“顾问”。

文件:app.routing.ts

const appRoutes: Routes = [
{ 
path: '',
component: AdvisorHomeComponent, 
canActivate: [AuthGuard], 
data: { 
    expectedRole: 'conseiller'
  } 
},
{
path: '',
component: ClientHomeComponent, 
canActivate: [AuthGuard], 
data: { 
  expectedRole: 'client'
  } 
}
{ path: '', component: LoginComponent},
{ path: 'login', component: LoginComponent }, 
{ path: 'register', component: RegisterComponent },

// otherwise redirect to login
{ path: '**', redirectTo: '/login' }
];

文件:auth.guard.ts

@Injectable()
export class AuthGuard implements CanActivate {
constructor(private router: Router) { }

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    const expectedRole = route.data.expectedRole;
    let currentUser = JSON.parse(localStorage.getItem('currentUser'));
    alert(expectedRole);
    if (currentUser && currentUser.statut == expectedRole) {
        // logged in so return true
        return true;
    }

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

我注意到的错误是,当我尝试以“conseiller”状态登录时,它可以工作,因为信息位于我的配置中的第一位,但如果我尝试以“client”状态登录,它不起作用,当我执行 alert(expectedRole);

时,它仍然向我显示“conseiller”状态

我认为我的路径设置或类似的东西有问题。放纵一下,我是 Angular 的初学者。 ;)

谢谢,

【问题讨论】:

  • 可能是错字 currentUser.statut 应该是 currentUser.status

标签: angular authentication frontend


【解决方案1】:

您定义了 3 次相同的路径(空的,默认路径)。它需要第一个。

您必须为客户端定义不同的路径,例如

{path: 'client', component: ClientHomeComponent, canActivate: [AuthGuard], data: { 
    expectedRole: 'client'
  } 
}

【讨论】:

  • 我同意你的观点,这就是为什么我试图按照你所说的给他们一个不同的,但在那之后我没有成功登录任何人。所以我真的不明白我必须在应用程序中的哪里设置他们的路径,因为这是将用户带到自己的面板的登录步骤。
  • 登录成功后你应该知道用户的角色是什么。只需将它们重定向到 /client/conseiller
  • 最后,我成功登录,两种状态都在 OnSubmit() 事件的登录组件中添加了结构条件。我注意到我对这行感到不安: this.router.navigate([this.returnUrl]); 我真的不知道这是否是一个“好的做法”,但它适用于我的假后端。或许,当我将前端连接到真正的后端时会有所不同!
【解决方案2】:

我认为有几种方法可以实现您的目标。 @PeS 为您提供了最简单的解决方案。我还是想做一些cmets。

我会创建以下内容:

  1. app-routing.module.ts
  2. auth.guard.ts
  3. authentication.service.ts
  4. user.service.ts
  5. local-storage.service.ts
  6. login.component.ts
  7. home.component.ts
  8. advisor-home.component.ts
  9. client-home.component.ts

app-routing.module.ts

const appRoutes: Routes = [
  { path: '', component: HomeComponent, canActivate: [AuthGuard] },
  { path: 'login', component: LoginComponent }, 
  { path: 'register', component: RegisterComponent },

  // otherwise redirect to login
  { path: '**', redirectTo: '/' }
];

auth.guard.ts

您的示例 auth.guard.ts 看起来不错。您必须对其进行编辑以从用户服务或类似的东西中获取角色,以反对路线数据。

home.component.ts

这个组件将是一个工厂。让用户查看他们拥有的角色,并根据该角色手动插入特定组件。因此,根据角色,您将添加advisor-home.component.tsclient-home.component.ts。这是一个StackBlitz,关于如何创建工厂。

【讨论】:

  • 感谢您的回复和意见!我想我的代码中有很多你的想法,但你是在谈论一个真正后端的实现吗?我问是因为我目前有一个假后端,但我很快就会将我的前端连接到一个真实的......
  • 没有。我的例子是纯粹的前端组件。您可以将后端数据存根到服务中,直到您准备好连接后端。
【解决方案3】:
export authGuardFn(data) {
  @Injectable({ providedIn: 'root' })
  class AuthGuard implements CanActivate {
  constructor(private router: Router) { }
  
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
      const expectedRole = data.expectedRole;
      let currentUser = JSON.parse(localStorage.getItem('currentUser'));
      alert(expectedRole);
      if (currentUser && currentUser.statut == expectedRole) {
          // logged in so return true
          return true;
      }
  
      // not logged in so redirect to login page with the return url
      this.router.navigate(['/login'], { queryParams: { returnUrl: state.url 
      }});
      return false;
   }
  }
  return AuthGuard 
}

【讨论】:

    猜你喜欢
    • 2019-03-15
    • 1970-01-01
    • 2019-01-19
    • 2019-02-26
    • 2017-09-26
    • 2018-11-22
    • 2019-03-23
    • 2021-12-16
    • 2019-03-03
    相关资源
    最近更新 更多