I am new to AngularJS, and I am a little confused of how I can use angular-"ui-router" in the following scenario:
I am building a web application which consists of two sections. The first section is the homepage with its login and signup views, and the second section is the dashboard (after successful login).
I have created an index.html
for the home section with its angular app and ui-router
config to handle /login
and /signup
views,
and there is another file dashboard.html
for the dashboard section with its app and ui-router
config to handle many sub views.
Now I finished the dashboard section and don't know how to combine the two sections with their different angular apps. How could I tell the home app to redirect to the dashboard app?
The solutions posted so far are needlessly complicated, in my opinion. There's a simpler way. The documentation of
ui-router
says listen to$locationChangeSuccess
and use$urlRouter.sync()
to check a state transition, halt it, or resume it. But even that actually doesn't work.However, here are two simple alternatives. Pick one:
Solution 1: listening on
$locationChangeSuccess
You can listen to
$locationChangeSuccess
and you can perform some logic, even asynchronous logic there. Based on that logic, you can let the function return undefined, which will cause the state transition to continue as normal, or you can do$state.go('logInPage')
, if the user needs to be authenticated. Here's an example:Keep in mind that this doesn't actually prevent the target state from loading, but it does redirect to the log-in page if the user is unauthorized. That's okay since real protection is on the server, anyway.
Solution 2: using state
resolve
In this solution, you use
ui-router
resolve feature.You basically reject the promise in
resolve
if the user is not authenticated and then redirect them to the log-in page.Here's how it goes:
Unlike the first solution, this solution actually prevents the target state from loading.
I think you need a
service
that handle the authentication process (and its storage).In this service you'll need some basic methods :
isAuthenticated()
login()
logout()
This service should be injected in your controllers of each module :
service.isAuthenticated()
method) . if not, redirect to /loginservice.login()
methodA good and robust example for this behavior is the project angular-app and specifically its security module which is based over the awesome HTTP Auth Interceptor Module
Hope this helps
I wanted to share another solution working with the ui router 1.0.0.X
As you may know, stateChangeStart and stateChangeSuccess are now deprecated. https://github.com/angular-ui/ui-router/issues/2655
Instead you should use $transitions http://angular-ui.github.io/ui-router/1.0.0-alpha.1/interfaces/transition.ihookregistry.html
This is how I achieved it:
First I have and AuthService with some useful functions
Then I have this configuration:
You can see that I use
to mark the state only accessible if is authenticated.
then, on the .run I use the transitions to check the autheticated state
I build this example using some code found on the $transitions documentation. I'm pretty new with the ui router but it works.
Hope it can helps anyone.
I have another solution: that solution works perfectly when you have only content you want to show when you are logged in. Define a rule where you checking if you are logged in and its not path of whitelist routes.
In my example i ask if i am not logged in and the current route i want to route is not part of `/login', because my whitelist routes are the following
so i have instant access to this two routes and every other route will be checked if you are online.
Here is my whole routing file for the login module
() => { /* code */ }
is ES6 syntax, use insteadfunction() { /* code */ }
I Created this module to help make this process piece of cake
You can do things like:
Or also
It's brand new but worth checking out!
https://github.com/Narzerus/angular-permission
First you'll need a service that you can inject into your controllers that has some idea of app authentication state. Persisting auth details with local storage is a decent way to approach it.
Next, you'll need to check the state of auth right before state changes. Since your app has some pages that need to be authenticated and others that don't, create a parent route that checks auth, and make all other pages that require the same be a child of that parent.
Finally, you'll need some way to tell if your currently logged in user can perform certain operations. This can be achieved by adding a 'can' function to your auth service. Can takes two parameters: - action - required - (ie 'manage_dashboards' or 'create_new_dashboard') - object - optional - object being operated on. For example, if you had a dashboard object, you may want to check to see if dashboard.ownerId === loggedInUser.id. (Of course, information passed from the client should never be trusted and you should always verify this on the server before writing it to your database).
** DISCLAIMER: The above code is pseudo-code and comes with no guarantees **