6
votes

Is there any way/best practice to hide unavailable pages from users in SAPUI5?

Let's see an example. I have a complex application with a user login page. Here customers can login to the application, and their role data is retrieved from a backend system. Based on these roles, some users are not permitted to create a new object. Only logged in users should be able to see application pages. I'm using routing, so functionalities like edit can be accessed by direct links as well.

Currently I'm using the onRouteMatched event handler in the Component.js, which checks for the current user session storage. If the user session is not found, it redirects the request to the login page.

The problem is that it shows the requested page for one or two seconds before navigating to the login page. It's really ugly.

Where should I implement such kind of functionality? Is there any hook method for this use case?

I think I need a hook method which is called before displaying the view matched by the given route and re-direct the call to the login page. Unfortunately I couldn't find any helpful document in this topic.

Thanks!

2
Just a thought: Make your view consist of two views. A placeholder (that is shown before onRouteMatched... maybe an empty Panel with busy: true) and the actual content (that replaces the placeholder when the user session is found). This does not solve your 1-2 sec delay. But it hides some of the ugliness.Marc
I have the exact same problem and solution like you. I came up with the solution to override the parse function in my Router, in this function you will only receive the hash of the url change and you have to parse the hash against your routes and your permissions. If the permission is granted i execute the super parse with the arguments otherwise i give the function empty arguments (["", undefined])deterministicFail

2 Answers

1
votes

The approach I've used for this is documented here Display a Target

To summarize, you can assign your view to a target in manifest.json, but not a route/pattern. This makes it inaccessible via direct links.

In your application, you can "display" the view instead of routing to it. The behavior is the same, except you do lose the history. So pressing the browser back button will behave differently, since you didn't actually route to a new view.

this.getOwnerComponent().getRouter().getTargets().display("edit", {
    fromTarget : "home"
});

If you still want the views to be accessible via direct link, you can use custom URL parameters in a view where all users are allowed to go.

For example, you can use the route

yourAppUrl.com/home?navTo=edit

And in your controller, use jQuery to parse the parameters.

_onPatternMatched: function() {
    var navParam = jQuery.sap.getUriParameters().get("navTo");
    if (navParam === "edit") {
        //handle your user verification here, then display the target
        this.getOwnerComponent().getRouter().getTargets().display("edit", {
            fromTarget : "home"
        });
    }
}
0
votes

Unfortunately there is no easy hook I know of. I'd love to see a beforeRouteMatched or alike on sap.ui.core.routing.Router but for now there is nothing...

Anyways you have various possibilities to achieve this. The most promising solution I can think of would be something like this:

Dynamically add your routes based on authorization

Store your route config in a simple object first and use routers addRoute method to dynamically add the allowed routes later based on the users authorization after your authorization call is back. Only thing you have to take care of additionally is the initial route the application was accessed with. You have to store that hash until your route config is set up and re-trigger the initial navigation after adding routes. Use HashChanger.setHash to achieve this.

Note

Client-side authorization checks are NEVER save and need to be double-checked in all backend services!