Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hiding routes in Aurelia nav bar until authenticated

Tags:

aurelia

Is there a proper way to hide items in the Aurelia getting started app behind some authentication.

Right now I'm just adding a class to each element based on a custom property. This feels extremely hacky.

    <li repeat.for="row of router.navigation" class="${row.isActive ? 'active' : ''}${!row.isVisible ? 'navbar-hidden' : ''}">
      <a href.bind="row.href">${row.title}</a>
    </li>
like image 587
JPinchot Avatar asked Mar 06 '15 01:03

JPinchot


2 Answers

There are two directions you can take here.

The first is to only show nav links in the nav bar when the custom property is set like you are. To clean it up a bit let's use the show binding -

  <li repeat.for="row of router.navigation" show.bind="isVisible" class="${row.isActive ? 'active' : ''}">
    <a href.bind="row.href">${row.title}</a>
  </li>

The issue here is you still need to maintain the custom property like you are already doing. The alternative is to reset the router. This basically involves building out a set of routes that are available when the user is unauthenticated and then a separate set once the user is authenticated -

this.router.configure(unauthenticatedRoutes);
// user authenticates
this.router.reset();
this.router.configure(authenticatedRoutes);

This gives you the flexibility to reconfigure the router whenever you need to.

like image 138
PW Kad Avatar answered Oct 21 '22 15:10

PW Kad


These answers are great, though for the purposes of authentication, I don't think any have the security properties you want. For example, if you have a route /#/topsecret, hiding it will keep it out of the navbar but will not prevent a user from typing it in the URL.

Though it's technically a bit off topic, I think a much better practice is to use multiple shells as detailed in this answer: How to render different view structures in Aurelia?

The basic idea is to send the user to a login application on app startup, and then send them to the main app on login.

main.js

export function configure(aurelia) {
  aurelia.use
    .standardConfiguration()
    .developmentLogging();

  // notice that we are setting root to 'login'
  aurelia.start().then(app => app.setRoot('login'));
}

app.js

import { inject, Aurelia } from 'aurelia-framework';

@inject(Aurelia)
export class Login {
  constructor(aurelia) {
    this.aurelia = aurelia;
  }
  goToApp() {
    this.aurelia.setRoot('app');
  }
}

I've also written up an in-depth blog with examples on how to do this: http://davismj.me/blog/aurelia-login-best-practices-pt-1/

like image 45
Matthew James Davis Avatar answered Oct 21 '22 15:10

Matthew James Davis