繁体   English   中英

访问管理组件正在使用 jwtHelper 在 angular 中实现基于角色的身份验证

[英]Access to the admin component am implementing role based authentication in angular using jwtHelper

我已经使用 Angular 6 创建了一个前端,我想要基于角色的授权,并使用 JWT 辅助服务实现。 不幸的是,我无法访问管理组件,它一直告诉我我没有被授权,而实际上我被授权访问管理组件

这是我的登录组件:

import { Component, OnInit } from '@angular/core';
import { AuthService } from 'src/app/auth.service';
import { Router } from '@angular/router';


@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {

  constructor(private Auth: AuthService,private router: Router) { }

  ngOnInit() {
  }
  loginUser(event)
  {
    event.preventDefault()
    const target = event.target
    const email= target.querySelector('#email').value
    const password = target.querySelector('#password').value

     this.Auth.getUserDetails(email,password).subscribe(data =>{
       if(this.Auth.isAuthenticated(),data.token)
       {
         localStorage.setItem('token',data.token);
         return true;
       }

       else
       {
         window.alert("Authentication Failed");
       }
     });
     console.log(email,password)
  }


}

这是我的角色.guard.ts

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service';
import decode from 'jwt-decode';

@Injectable({
  providedIn: 'root'
})
export class RoleGuard implements CanActivate {

  constructor( public auth: AuthService,public router: Router) {}
  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {

    // this will be passed from the route config
    // on the data property
    const admintype = route.data.admintype;
    const token = localStorage.getItem('token');
    // decode the token to get its payload
    const tokenPayload = decode(token);
    if (
      !this.auth.isAuthenticated() || 
      tokenPayload.role !== admintype
    ) {
      this.router.navigate(['login']);
      return false;
    }

    return true;
  }

}

这是我的 auth.guard.ts

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service';
import { UserService } from './user.service';
import { map } from 'rxjs/operators';
import { Router } from '@angular/router'


@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {


  constructor(private auth: AuthService,private router:Router, private user: UserService)
  {

  }


  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {


      if (!this.auth.isAuthenticated()) {
        this.router.navigate(['login']);
        return false;
      }

        return true


    }

}

这是我的 auth.service.ts

import { Injectable } from '@angular/core';
import{ HttpClient } from '@angular/common/http';
import { JwtHelperService } from '@auth0/angular-jwt';

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  uri : String = 'http://localhost:4000';

  private jwtHelper = new JwtHelperService();

  constructor(private http: HttpClient) { }

  public isAuthenticated(): boolean {
    const token = localStorage.getItem('token');
    // Check whether the token is expired and return
    // true or false

    if(token==null)
    {
      return false;
    }
    else{
    return !this.jwtHelper.isTokenExpired(token);

    }
  }

  getUserDetails(email: String,password:String){

    //post these details to the database
    return this.http.post(`${this.uri}/auth`,{ email,password});
  }
  signupadminsections(email:String,password:String,name:String,admintype:String,college:String,department:String)
  {
    //add new admin section
    return this.http.post(`${this.uri}/register`,{ email,password,name,admintype,college,department});
  }
}

我的 app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Component } from '@angular/core';
import { RouterModule } from '@angular/router';
import { AuthGuard } from './auth.guard';
import { HttpClientModule } from '@angular/common/http';
import { MatTableModule, MatInputModule, MatSelectModule
 } from '@angular/material'
 import { RoleGuard } from './role.guard'

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HomeComponent } from './components/home/home.component';
import { LoginComponent } from './components/login/login.component';
import { AdmindashboardComponent } from './components/admindashboard/admindashboard.component';
import { AuthService } from './auth.service';
import { UserService } from './user.service';
import { ViewallstudentsComponent } from './components/viewallstudents/viewallstudents.component';
import { AdminComponent } from './components/admin/admin.component';
import { AddsectionadminsComponent } from './components/addsectionadmins/addsectionadmins.component';
import { PagenotfoundComponent } from './components/pagenotfound/pagenotfound.component';
import { from } from 'rxjs';
import { JwtHelperService, JwtModule } from '@auth0/angular-jwt';

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    LoginComponent,
    AdmindashboardComponent,
    ViewallstudentsComponent,
    AdminComponent,
    AddsectionadminsComponent,
    PagenotfoundComponent
  ],
  imports: [
    JwtModule,
    MatSelectModule,
    MatTableModule,
    MatInputModule,
    BrowserModule,
    HttpClientModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    RouterModule.forChild([
      {
        path: 'login',
        component: LoginComponent

      },
      {
        path: 'admin',
        component:AdminComponent,
        data:{
          admintype:['admin']
         },
        canActivate :[RoleGuard],
      },
      {
       path:'addsectionadmin',
       component:AddsectionadminsComponent,
       data:{
        admintype:['admin']
       },
       canActivate:[AuthGuard]
      },
      {
        path: 'admindashboard',
        component: AdmindashboardComponent,
        data:{
          admintype:['sectionadmin']
         },
        canActivate: [RoleGuard]
      },
      {
         path:'viewallstudents',
         component:ViewallstudentsComponent,
         canActivate:[AuthGuard]
      },
      {
        path:'**',redirectTo:'pageNotFound'
      },
      {
        path:'',redirectTo:'login',pathMatch:'full'
      }


    ])
  ],
  providers: [ AuthGuard, UserService,AuthService,RoleGuard,JwtHelperService],
  bootstrap: [AppComponent]
})
export class AppModule { }

如果问题被标记为 HTTP 状态:403 表示“未授权访问”,则可能是由于以下几个原因:

  1. localstorage.getItem('token')总是返回 false,尝试查看浏览器中的 localstorage ( F12 -> Application -> expand the local storage ) 以确认您的令牌在那里
  2. 令牌在localStorage中,但由于getItem('token')的不同步性,检查失败
  3. this.jwtHelper.isTokenExpired(token)总是返回假值

对您的代码稍作更改,一切都会按预期进行:

import { Injectable } from '@angular/core';
import{ HttpClient } from '@angular/common/http';
import { JwtHelperService } from '@auth0/angular-jwt';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  uri : String = 'http://localhost:4000';
  public isLoggedIn = new BehaviorSubject<boolean>(false); // {1}
  token: string = "";
   canActivatestateChanged = false;

  private jwtHelper = new JwtHelperService();

  constructor(private http: HttpClient) { }

   //Getter for the Behavioral variable `isLoggedIn` to use in the Guards
   get isLoggedIn() {

        return this.isLoggedIn.asObservable(); 
    }

  public isAuthenticated() : boolean {
    const token = this.getToken()
    // Check whether the token is expired and return
    // true or false
    if (token === undefined || token  === "") {
                this.isLoggedIn.next(false);
                this.canActivatestateChanged  = false;
                this.router.navigate(['/login']);                
     }else{
           if(!this.jwtHelper.isTokenExpired(token)){
                this.isLoggedIn.next(true);
                this.canActivatestateChanged  = true;
               this.router.navigate(['/admin']);

            }else{
            this.isLoggedIn.next(false);
            this.canActivatestateChanged  = false;
            this.router.navigate(['/login']);
           }
      }
    return this.canActivatestateChanged

  }

  getUserDetails(email: String,password:String){

    //post these details to the database
    return this.http.post(`${this.uri}/auth`,{ email,password});
  }
  signupadminsections(email:String,password:String,name:String,admintype:String,college:String,department:String)
  {
    //add new admin section
    return this.http.post(`${this.uri}/register`,{ 
     email,password,name,admintype,college,department});
  }

//You may need this to get the token from the local storage
public getTokenFromLocalStorage(): string {
        return localStorage.getItem('token');
 }
}

并检查 RoleGuard.ts 让我们有这个代码

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service';
import { UserService } from './user.service';
import { map } from 'rxjs/operators';
import { Router } from '@angular/router'


@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {


constructor(private auth: AuthService,private router:Router, private user: UserService)
  {

  }

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {

     return this.auth.isLoggedIn       // {1}
      .take(1)                               // {2} 
      .toPromise().then((isLoggedIn: boolean) => {
      try {
          if (!this.auth.isAuthenticated()) {
              return false;
            }
          else {
              return true;
            }
    } catch(e){
     console.log(e);
    }

}
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM