【问题标题】:Angular 6: How to implement route guard with auth serviceAngular 6:如何使用身份验证服务实现路由保护
【发布时间】:2018-09-27 05:06:35
【问题描述】:

如何在路由保护中使用来自 auth.service.ts 的数据。从 auth.service.ts 我使用验证令牌 api 来检查有效性(在邮递员返回 {"valid" : true} 中测试)。但我不明白如何使用路由保护来实现。

auth.service.ts 验证令牌的代码。如果令牌有效,则返回 true

 verifyToken(id:string, token: string) {
    const params = new HttpParams().set('a', id).set('b', token);

    this.base_url = environment.MYAPI_REST_API_URL;

    this.customersObservable = this.httpClient.get(this.base_url +'/registration/application/verifyConfirmationToken', {params});

     this.data = JSON.stringify(this.customersObservable);

     return this.data;
}

路由守卫代码

 canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    this.route.queryParams.subscribe(params => {
        this.id = params['a'];
        this.token = params['b'];
    });

    if (this.auth.verifyToken(this.id,this.token)) {
        // 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 }});
    // window.location.href='http://www.cnn.com/';
    return false;
}

【问题讨论】:

  • 在验证令牌方法中,您应该验证令牌,但这就是您在该方法中没有做的事情,您可以使用angular-jwt库来检查令牌是否有效github.com/auth0/angular2-jwt
  • 为什么要在验证令牌方法中进行api调用?只是为了验证令牌?
  • .subscribe 是异步的,您不会立即获取数据,因此在 verifyToken arg 中将取消设置
  • 不清楚你所做的实现。只需从 verifyToken 方法返回一个 boolean 并在 canActivate 方法中告知。 canActive 方法只想返回 true 或 false。不要在 canActivate 方法中添加这么多责任

标签: angular angular5 angular6


【解决方案1】:

是的,您可以通过创建 Auth Guard 服务来做到这一点。

// Auth Gaurd Service
// In AuthGaurdService

@Injectable()
class CanTokenActive implements CanActivate {
  constructor(private currentUser: UserToken) {}
 
  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean>|Promise<boolean>|boolean {
    // Logic to check token is exist or not.
  }
}


// In routhing module

@NgModule({
  imports: [
    RouterModule.forRoot([
      {
        path: 'home',
        component: Home,
        canActivate: ['canTokenActive']
      }
    ])
  ]
 })
class AppModule {}

【讨论】:

    【解决方案2】:
    1) 
    ng generate guard auth   [ Create guard, the file name would be like 
    auth.guard.ts ]
    
    import { Injectable } from '@angular/core';
    import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from 
    '@angular/router';
    import { Observable } from 'rxjs/Observable';
    import { AuthService } from './auth.service';
    import {Router} from '@angular/router';
    @Injectable()
    export class AuthGuard implements CanActivate {
      constructor(private auth: AuthService,
        private myRoute: Router){
      }
    
      canActivate(
        next: ActivatedRouteSnapshot,
        state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | 
       boolean {
        if(this.auth.isLoggednIn()){
          return true;
        }else{
          this.myRoute.navigate(["login"]);
          return false;
        }
      }
    }
    
    
    2)  ng g c login  [Create login page ]
    ng g c nav  [Create nav page ]
    ng g c home  [Create home page ]
    ng g c registration  [Create registration page ]
    
    
    3) App.module.ts file add below contents
    
    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { RouterModule,Router,Routes } from '@angular/router';
    import { ReactiveFormsModule,FormsModule } from '@angular/forms';
    import { AuthService } from './auth.service';
    import { AuthGuard } from './auth.guard';
    
    import { AppComponent } from './app.component';
    import { LoginComponent } from './login/login.component';
    import { NavComponent } from './nav/nav.component';
    import { HomeComponent } from './home/home.component';
    import { RegistrationComponent } from 
    './registration/registration.component';
    
    // canActivate added for AuthGuard.
    // Add in Providers: [AuthService,AuthGuard],
    
    const myRoots: Routes = [
      { path: '', component: HomeComponent, pathMatch: 'full' , canActivate: 
      [AuthGuard]},
      { path: 'register', component: RegistrationComponent },
      { path: 'login', component: LoginComponent},
      { path: 'home', component: HomeComponent, canActivate: [AuthGuard]}
    ];
    
    @NgModule({
      declarations: [
        AppComponent,
        LoginComponent,
        NavComponent,
        HomeComponent,
        RegistrationComponent
      ],
      imports: [
        BrowserModule,ReactiveFormsModule,FormsModule,
        RouterModule.forRoot(
          myRoots,
          { enableTracing: true } // <-- debugging purposes only
        )
      ],
      providers: [AuthService,AuthGuard],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    
    
    4) Add link in nav.component.html
    
      <p color="primary">
      <button  routerLink="/home">Home</button>
      <button  *ngIf="!auth.isLoggednIn()" 
      routerLink="/register">Register</button>
      <button  *ngIf="!auth.isLoggednIn()" routerLink="/login">Login</button>
      <button  *ngIf="auth.isLoggednIn()" 
      (click)="auth.logout()">Logout</button>
      </p>
    
    
    4.1)  Add in nav.component.ts file
    
    import { Component, OnInit } from '@angular/core';
    import { AuthService } from '../auth.service';
    @Component({
      selector: 'app-nav',
      templateUrl: './nav.component.html',
      styleUrls: ['./nav.component.css']
    })
    export class NavComponent implements OnInit {
      constructor(public auth: AuthService) { }
      ngOnInit() {
      }
    }
    
    
    5) 
    ng g service auth  [Create service page Add below code in authservice.ts]
    
    import { Injectable } from '@angular/core';
    import { Router } from '@angular/router';
    @Injectable()
    export class AuthService {
      constructor(private myRoute: Router) { }
      sendToken(token: string) {
        localStorage.setItem("LoggedInUser", token)
      }
      getToken() {
        return localStorage.getItem("LoggedInUser")
      }
      isLoggednIn() {
        return this.getToken() !== null;
      }
      logout() {
        localStorage.removeItem("LoggedInUser");
        this.myRoute.navigate(["Login"]);
      }
    }
    
    
    6) add content in login.ts
    
    import { Component, OnInit } from '@angular/core';
    import { FormBuilder, Validators } from '@angular/forms';
    import { Router } from '@angular/router';
    import { AuthService } from '../auth.service';
    @Component({
      selector: 'app-login',
      templateUrl: './login.component.html',
      styleUrls: ['./login.component.css']
    })
    export class LoginComponent implements OnInit {
      form;
      constructor(private fb: FormBuilder,
        private myRoute: Router,
        private auth: AuthService) {
        this.form = fb.group({
          email: ['', [Validators.required, Validators.email]],
          password: ['', Validators.required]
        });
      }
      ngOnInit() {
      }
      login() {
        if (this.form.valid) {
          this.auth.sendToken(this.form.value.email)
          this.myRoute.navigate(["home"]);
        }
      }
    }
    
    
    6.1)  add in logincomponent.html page
    
    <form [formGroup]="form" (ngSubmit)="login()">
    <div>
    <input  type="email" placeholder="Email" formControlName="email" />
    </div>
    <div>
    <input  type="password" placeholder="Password" formControlName="password" 
    />
    </div>
    <button type="submit" color="primary">Login</button>
    </form>
    
    
    7) Add below code in app.component.html
    
    <app-nav></app-nav>
    <router-outlet></router-outlet> 
    

    【讨论】:

      猜你喜欢
      • 2021-12-16
      • 1970-01-01
      • 1970-01-01
      • 2020-05-10
      • 2021-11-07
      • 2013-03-27
      • 2016-04-21
      • 1970-01-01
      • 2018-05-21
      相关资源
      最近更新 更多