In native Angular, there’s this canActivate
interface which is used to decide whether a page should be loaded or not, based on a boolean.
The closest I can think of in Ionic is the ionViewCanEnter
.
Unlike the ioncViewCanEnter
, the canActivate
can be applied to a route and its related children. It is extremely convenient.
In Ionic, can I apply a single ionViewCanEnter
to multiple pages? Would that involve having to let my component exported classes extend a class where the ionViewCanEnter
is rigged to behave like a guard?
I’m curious because I currently have some pages to guard based on auth, and I’m scared I might end up duplicating code into some 10 or more pages, whereas if I could write the guard once, and just apply to as many as I want, it’ll be a lot easier.
If there’s an implementation of this sort somewhere, please point me to it.
Thanks.
ionVIewCanEnter is per page, but routing is getting completely revamped, so I don’t know what the answer to your question will be in 6 months. However, I don’t see a code duplication issue. You can create guardProvider, and have each ionViewCanEnter query guardProvider whether criteria to enter are satisfied. It isn’t as simple as not creating a service, but you only have to write the code once.
In fact, that’s what I’m currently doing. The code duplication I mentioned was referring to the many ionViewCanEnter
I will have to write. With angular, all the routes are in one place, then slapping the canActivate
on top of the routes mean every route including children is guarded.
Currently doing the approach you suggest, and it is working fine. The many ionViewCanEnter
i have to write is what I worry.
I think that’s your best option right now.
I don’t understand the value of this sort of guard mentality. Any actual security has to be done server-side, so anything within the client app is merely cosmetic. Instead of thinking defensively in a page of “can I be entered?”, why not actively eliminate or disable the navigation activity path that leads to the page until the proper authorization state has been reached?
In case you’re referring to any use case for something like canActivate
, don’t forget the Address bar is there where a user can enter the url directly.
Therefore, this “actively eliminate or disable navigation” isn’t always the case.
FWIW, I have actively eliminated links pointing areas where auth is required. However, because I’ve done that doesn’t mean every user of the application will follow such steps.
I prefer to handle all this via a subscription in the app component that basically says:
authNotifier.subscribe(authed => {
if (authed) {
this.rootPage = DashboardPage;
} else {
this.rootPage = LoginPage;
}
});
Assuming the authNotifier
fires one way or the other eventually on startup, this should take care of redirecting the user to somewhere appropriate regardless of initial entry point.
1 Like
The Ionic router is not set up for this. (Yeah, there’s deeplinks etc., but that behavior is not natural.) It’s intended for handheld devices, “native experience.” Redoing routing for PWA’s is the project taking place right now. If you’re coding for a desktop browser with the current Ionic router, expect to code lots of kluges.
1 Like
And I’m wondering, does a user have to log in before can read help/about/contact pages?
I get your point, @rapropos, but let’s be honest, not every applications follows the either log in or not approach.
So my question is, how do you only auth a select few pages (i.e CRUD pages), however all other static pages aren’t authed?
Depends on the particular app. There isn’t any need to make them if you don’t want to; where I had LoginPage
could just as easily be GuestDashboardPage
that has a subset of functionality appropriate for guests.
Sure, but if you’re talking about having certain functionality being limited to somebody with some sort of authentication credential, even if you don’t call it login/logout, it functionally seems equivalent to me.
I’m sorry to be stubborn about this, but I really want people to understand that you fundamentally cannot limit access to certain parts of a mobile app using merely techniques like canEnter
guards. Unless you go to extremes like using a KDF to encrypt the content, anybody with a copy of the app binary has access to any page and controller code that is contained therein.
So let’s say we have a publishing app. Guests can read unlocked stories. Registered users can read all stories. Editors can publish new stories.
It might be tempting to try to use route guards to restrict access to the “Publish” page to only editors. It provides no meaningful protection to do so, however. The only way this can be done properly is on the server side, where the server only accepts POST requests to the /publish
endpoint when they contain a valid JWT for an editor and returns only the unlocked subset of articles to GET requests for /stories
unless there is a similar JWT for a registered user.