Angular2 Router - Anyone know how to use canActivate in app.ts so that I can redirect to home page if not logged in

前端 未结 5 402
误落风尘
误落风尘 2020-12-05 12:06

Angular2 Router - Anyone know how to use canActivate in app.ts so that I can redirect to home page if not logged in

I\'m using typescript and angular 2.

相关标签:
5条回答
  • 2020-12-05 12:09

    These answers are no longer valid in the RC candidate as of 22/6/16.

    There is a lot of talk a new solution for @CanActivate annotation but you can revert back to using the angular-2/router-deprecated version in the interim.

    If you want to follow the updates to this area if you want to use the newer router implementation please check out these two github issues:

    • Router OnActivate does not delay render until promise settles #6611
    • Equivalent to resolve in Component Router? #4015

    Sorry there is no complete answer right now, if I see any further progress on this I'll update this reply. I'm searching for an elegant solution as well.

    For the interim I just used a ngIf='fooObject' in a div to check for object being used in a child directive is populated/truthy and then render the rest of the components html. It's not ideal but it does work consistently right now. May help you or not depending on your use case. I don't need to redirect, only check my data has resolved for the display of my component.

    0 讨论(0)
  • 2020-12-05 12:12

    From here:

    https://angular.io/docs/ts/latest/api/router/CanActivate-decorator.html

    CanActivate is an annotation, not a function. You use it like this:

    @Component({selector: ... })
    @CanActivate(()=>console.log('Should the component Activate?'))
    class AppComponent {
    
    }
    

    routerOnActivate IS a function you use inside your component:

    https://angular.io/docs/ts/latest/api/router/OnActivate-interface.html

    0 讨论(0)
  • 2020-12-05 12:14

    With the new beta release of the router, you can also see my answer here on how to use the CanActivate interface:

    https://stackoverflow.com/a/38369948/1944351

    Using the decorator as mentioned in other answer is fine too.

    0 讨论(0)
  • 2020-12-05 12:30

    @CanActivate was removed. See more details here.

    You should now use route.canActivate

    0 讨论(0)
  • 2020-12-05 12:35

    So the documentation looks like this is what it exports.

    export CanActivate(options : CanActivateAnnotation) : (hook: (next: ComponentInstruction, prev: ComponentInstruction) =>
                         Promise<boolean>| boolean) => ClassDecorator
    
    @CanActivate((next, prev) => {
          // This must prove to be true for the component @ this route to load
          if(next.urlPath != '/Login'){ 
             return Promise.resolve(this._authService.getIsAuth() 
             && localStorage.getItem('authToken')
          }
          /*
           If CanActivate returns or resolves to false, the navigation is 
           cancelled. If CanActivate throws or rejects, the navigation is also
           cancelled. If CanActivate returns or resolves to true, navigation 
           continues, the component is instantiated, and the OnActivate hook of 
           that component is called if implemented.
          */
       }
    );
    

    At the bottom of the Angular2 documentation they add this snippet : exported from angular2/router https://angular.io/docs/ts/latest/api/router/CanActivate-decorator.html

    So if you are looking to do redirection from a higher level. You would not use the CanActivate decorator you would do the following.

    import {Directive, Attribute, ElementRef, DynamicComponentLoader} from 'angular2/core';
    import {Router, RouterOutlet, ComponentInstruction} from 'angular2/router';
    import {Login} from '../login/login';
    import {UserService} from '../../Services/userService'; // a service to handle auth
    
    @Directive({
      selector: 'router-outlet'
    })
    export class AuthRouterOutlet extends RouterOutlet {
      publicRoutes: any;
      private parentRouter: Router;
    
      constructor(private _userService:UserService, _elementRef: ElementRef, _loader: DynamicComponentLoader,
                  _parentRouter: Router, @Attribute('name') nameAttr: string) {
        super(_elementRef, _loader, _parentRouter, nameAttr);
    
        this.parentRouter = _parentRouter;
        this.publicRoutes = {
          '/login': true,
          '/signup': true
        };
        // publicRoutes will be the routes auth is not needed for.
      }
    
      activate(instruction: ComponentInstruction) {
        var url = this.parentRouter.lastNavigationAttempt;
        if (!this.publicRoutes[url] && this._userService.getAuth()) {
          // todo: redirect to Login, may be there a better way?
          this.parentRouter.navigateByUrl('/login');
        }
        return super.activate(instruction);
        // we return super.activate(instruction) here so the router can activate the requested route and it's components.
      }
    }
    

    This implementation handles any new request to a directive and runs the activate function where your route authentication logic will be. The code above would be called something like AuthRouterOutlet. and you would have to add it to your app.ts via the

    directives: [ AuthRouterOutlet]
    
    0 讨论(0)
提交回复
热议问题