具有重定向功能的Angular 2 AuthGuard服务?

时间:2016-08-17 16:52:02

标签: javascript angular

我正在构建一个在仪表板路由上实现CanActivate的应用程序。它在页面重新加载时工作正常,我检查用户服务中的标志以查看用户是否登录。默认情况下,此标志为false,将用户踢出登录。另外在页面重新加载时我试图在localStorage中使用令牌获取使用数据,如果获取成功,我希望它们能够留在仪表板上。问题是我看到了登录的一瞥并且不得不手动将它们重定向到仪表板。有没有办法解决这个问题,直到它检查API之后authGuard没有做任何事情?代码在这里:https://github.com/judsonmusic/tfl

仪表板:

import{ Component , ViewChild} from '@angular/core';
import {LoginComponent} from "../login.component";
import {UserService} from "../user.service";
import {SimpleChartComponent} from "../charts/simpleChart.component";
import {AppleChartComponent} from "../charts/appleChart.component";
import {BarChartComponent} from "../charts/barChart.component";
import {DonutChartComponent} from "../charts/donutChart.component";
import {AlertComponent} from 'ng2-bootstrap/ng2-bootstrap';
import {ModalDemoComponent} from "../modals/modalDemoComponent";
import {NgInitHelperComponent} from "../helpers/nginit.helper.component";
import {ModalDirective} from "ng2-bootstrap/ng2-bootstrap";
import {MODAL_DIRECTIVES, BS_VIEW_PROVIDERS} from 'ng2-bootstrap/ng2-bootstrap';


@Component({
  selector: 'dashboard',
  templateUrl: '/app/components/dashboard/dashboard.component.html',
  providers: [UserService, BS_VIEW_PROVIDERS],
  directives: [SimpleChartComponent, AppleChartComponent, BarChartComponent, DonutChartComponent, AlertComponent, ModalDemoComponent, NgInitHelperComponent, ModalDirective]
})
export class DashboardComponent  {

  public areas:any;

  constructor() {

    this.areas = [

      "Spiritual",
      "Habits",
      "Relationships",
      "Emotional",
      "Eating Habits",
      "Relaxation",
      "Exercise",
      "Medical",
      "Financial",
      "Play",
      "Work/ Life Balance",
      "Home Environment",
      "Intellectual Well-being",
      "Self Image",
      "Work Satisfaction"
    ]

  }
}

路线:

import { Routes, RouterModule } from '@angular/router';
import { AboutComponent } from './components/about.component';
import {PageNotFoundComponent} from "./components/pageNotFound.component";
import {HomeComponent} from "./components/home.component";
import {DashboardComponent} from "./components/dashboard/dashboard.component";
import {SurveyComponent} from "./components/survey/survey.component";
import {ResourcesComponent} from "./components/resources.component";
import {LogoutComponent} from "./components/logout.component";
import {AuthGuard} from "./components/auth-guard.service";
import { loginRoutes, authProviders }      from './login.routing';
import {LoginComponent} from "./components/login.component";

const appRoutes:Routes = [
  { path: '', component: HomeComponent },
  { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
  { path: 'logout', component: LogoutComponent },
  { path: 'resources', component: ResourcesComponent },
  { path: 'survey', component: SurveyComponent },
  { path: 'about', component: AboutComponent},
  { path: 'login', component: LoginComponent},
  { path: '**', component: PageNotFoundComponent}
];

export const appRoutingProviders: any[] = [
  authProviders
];
export const routing = RouterModule.forRoot(appRoutes);

登录路线:

import { Routes }         from '@angular/router';
import { AuthGuard }      from './components/auth-guard.service';
import { AuthService }    from './components/auth.service';
import { LoginComponent } from './components/login.component';
export const loginRoutes: Routes = [
  { path: 'login', component: LoginComponent }
];
export const authProviders = [
  AuthGuard,
  AuthService
];

6 个答案:

答案 0 :(得分:60)

AuthGuard执行此操作

@Injectable()

export class AuthGuard implements CanActivate {

auth: any = {};

constructor(private authService: AuthService, private router: Router) {

}

canActivate() {
    if (/*user is logged in*/) {
        this.router.navigate(['/dashboard']);
        return true;
    }
    else {
        this.router.navigate(['/Login']);
    }
    return false;
}
}

答案 1 :(得分:3)

我实际上已将我的服务更改为此并且可以正常运行:

import { Injectable }             from '@angular/core';
import { CanActivate, Router,
ActivatedRouteSnapshot,
RouterStateSnapshot }    from '@angular/router';
import { AuthService }            from './auth.service';
import {UserService} from "./user.service";

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private authService: AuthService, private router: Router, private userService: UserService) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {



    if (this.authService.isLoggedIn){
      console.log('ATUH GUARD SAYD THEY ARE ALREADY LOGGED IN!');
      return true;


    }else {


      this.userService.getUser().subscribe((user) => {

        console.log('AUTH GUARD GETTING USER', user);

        if (user._id) {
        this.authService.isLoggedIn = true;
        // Store the attempted URL for redirecting
        this.authService.redirectUrl = state.url;
        this.router.navigate(['/dashboard']);
        return true;
        }else{
          console.log('Validation Failed.');
          localStorage.clear();
          this.router.navigate(['/login']);
          return false;
        }


      }, (error) => {
        console.log('There was an error.');
        this.router.navigate(['/login']);
        return false

      });

    }


  }
}

答案 2 :(得分:1)

您现在可以从AuthGuard返回UrlTree,或者返回布尔值true / false。

https://blog.angularindepth.com/new-in-angular-v7-1-updates-to-the-router-fd67d526ad05

惊奇的人还没有提到这一点!抱歉,暂时没有示例,但是这个想法很简单。

答案 3 :(得分:0)

以下是使用UrlTree正确处理防护中的重定向的方法

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivateChild {
  constructor(
    private authService: AuthService,
    private logger: NGXLogger,
    private router: Router
  ) {}

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

    return this.authService.isLoggedIn().pipe(
      map(isLoggedIn => {
        if (!isLoggedIn) {
          return this.router.parseUrl('/login');
        }

        return true;
      })
    );
  }
}

非常感谢Angular In Depth的解释!

答案 4 :(得分:0)

我这样解决了它,并在AuthGuard中使用了它

isLoggedIn(): Observable<boolean> {
return this.afAuth.authState
  .pipe(
    take(1),
    map(user => {
        return !!user;
      },
      () => {
        return false;
      }
    ),
    tap(loggedIn => {
        if (!loggedIn) {
          this.router.navigate(['/']);
        }
      }
    ));
}

答案 5 :(得分:0)

这就是我为canActivate所做的

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    // ensure the user is properly logged in and the url he's requesting is within his right
    if (this.authSvc.getRole().trim().length > 0 && this.authSvc.getToken().trim().length > 0
      && state.url.includes(this.authSvc.getRole().trim())) {
      let url: string;
      // base on user's role send to different url to check
      if (this.authSvc.getRole().trim() === 'client') {
        url = ClientAccessRequestUrl;
      } else {
        url = AdminAccessRequestUrl;
      }
      return this.http.post<AccessRequestResponse>(url, {
        token: this.authSvc.getToken(),
      }).pipe(map(response => {
        console.log('response is:', response);
        // check successful then let go
        if (response.reply === true) {
          return true;
          // unless go to visitor site
        } else {
          return this.router.createUrlTree(['/visitor']);
        }
      }));
    } else {
      return this.router.createUrlTree(['/visitor']);
    }
  }