Ionic 2 Route Guards?


#4

I haven’t used this technique with Ionic yet, so I’m not certain about where to hook it into the lifecycle and navigation controller, but I believe the fundamental idea should translate.

Something like this:

<div gated>
... authorized-only content
</div>
@Directive({
  selector: '[gated]'
})
export class AuthenticationGatekeeper {
  constructor(nav:NavController, auther:Authenticator) {
    if (!auther.isAuthenticated()) {
      nav.push(LoginPage);
    }
  }
}

…I have used in vanilla Angular applications before.


Disable Deep Linking?
#5

With that comes a little problem about transitions, if that push triggers before the transition animation finishes the navigation breaks, for me happens the same when i open an alert too soon.


#6

As you’re actively involved in all the issues I’ve seen on this topic, there probably isn’t much I can say to you that you haven’t already seen, but hopefully those are implementation details that don’t interfere with the notion of using an attribute directive to achieve your goals, at least until the new router is usable with Ionic.


#7

I guess i’ll have to stick with ionViewWillEnter page life cycle hook for the time being, however idk how would it play with transitions, i’ll test tomorrow.


#8

Just to chime in on this, there is still a lot of working being done on the router from both ionic’s side and angular’s side. I’d hold off for now on things like this. We have some new features coming down the pipeline that will make this easy.


#9

In my current situation i have this implemented as a global service that holds the login state, then in each component i check with the service what the login token is and if none, redirect to login, i hope in the future, instead of opening the page and then redirecting, i could check before and cancel or redirec to root instead of those 2 routing steps.


#10

@mhartington Man can i just insert the new router with the IonicBootstrap() method? i’m about to start a project where route guards would shine like diamond, as far as i’ve read somewhere someone of the staff said the angular 2 router was deactivated because was under heavy dev changes.

Does that mean that if we try to use it Ionic blocks the router? or just that you guys don’t support it and thus we lose the navigation transitions when using it?


#11

Hi @luchillo17,
for my last news ionic2 will never inlcude new angular2 router, but they will release their own router using urls. But this will happening only in a couple of weeks, probably for beta.12 or RC.1

Can you share your solution? There are many other users like us, which needs this as soon as possible.


#12

We’re delaying the process, right now i want to test if putting the new router by my own in the IonicBootstrap() method would work, and how would that play with the styles of ionic components, off course if it does indeed work, since as i mentioned before i read that Ionic disabled the Angular router.


#13

I don’t think it would work your way. But let us know your result! Thx


#14

@mhartington Any updates on this ? Actually router Authorization is becoming really important according to the user roles
@luchillo17 Can you please share what worked for you ? I found somewhere that CanActivate can be used for this althogh still not sure, so anyone used this can give his feedbacks

[1] - http://youknowriad.github.io/angular2-cookbooks/stateless-authentication.html
[2] - canActivate on ionic2?


#15

@gaurav Sorry dude, not much to tell, right now we let the page transition and ionViewDidEnter we ask for the permissions, that’s just the other way around i would like it to work, i would like to have it ask before the navigation starts so the page only get’s open when the user does have the permission instead of opening then validating.

Idk if CanActivate works in Ionic since that one was from the deprecated router, also the Ionic router doesn’t make any mention about similar functionality in their router, i’ll have to test.


#16

To manage Authentication and Authorization, I followed the post below and I wrote an interceptor of every http requests of my app to my server. In that way, if the server send back to the app “not logged in”, this will be catched and the user will then be redirected to the login screen.

https://www.illucit.com/blog/2016/03/angular2-http-authentication-interceptor/

The only difference I implemented in Ionic versus the link above is that instead of doing the redirect in the service itself I use an EventEmitter (from the service to the app root).


#17

@reedrichards could you share your EventEmitter code please? thanks


#18

Nothing special there

In the interceptor

requestIntercepted:EventEmitter<number> = new EventEmitter<number>();

And where you want to subscribe to the event

(<YourInterceptor> this.http).requestIntercepted.subscribe((errorCode: number) => this.doStuffsInCaseItsNotOk());

#19

can we use the ionViewWillEnter() ?


#20

For there record and since I can’t edit my EventEmitter code above, I just gonna add that here: it’s kind of a bad practice to use EventEmitter (except when it goes to components output). Therefore I change that EventEmitter code with an Observable like following:

private requestInterceptedSource: Subject<number> = new Subject<number>();
requestIntercepted:Observable<number> = this.requestInterceptedSource.asObservable();

The subscription part stay the same.


#21

Just recently I created a little tutorial on using Auth Guards!

Right now with Ionic 3.1 I think there might be a small glitch, so while in the tutorial we can catch whether we are allowed to enter a page inside the .catch() block, the result currently only comes to a .then() block!


#22

this tuto is really far from Route gards. not revealant at all.


#23

@luchillo17 you can try a slimmer and more elegant approach using the TypeScript decorators.

You must create a decorator to use in a class, this decorator can implement the authentication check on the ionViewWillEnter method, as you wanted. Then you can use this decorator in your page class that should be protected, like this:

@AuthGuard()
@IonicPage()
@Component({
    selector: 'page-start',
    templateUrl: 'start.html',
})
export class StartPage {}

Where @AuthGuard() is the decorator created to do this user verification.
You could also implement parameters in your decorator, for example, to verify that the user also has permission to access a certain page, this in case your app has several levels of access per user.
So in addition to the decorator check if the user is logged in, it also checks if the user has access to the resource:

@AuthGuard('shows, comments, episodes')
@IonicPage()
@Component({
    selector: 'page-start',
    templateUrl: 'start.html',
})
export class StartPage {}