3

So this is my problem.

I can successfully login from my angularJS app using the auth factory i made that communicates to my pp rest API. lets say Auth.login(user) -> (POST) myapi.com/user/login: the response is the user object that Auth saves locally. Thus Auth.getCurrentUser() returns local user object.

my rest API, i also have a myapi.com/user/get_loggedin_user which returns the current logged in user (using the php session). So if Auth.getCurrentUser should actually check if local user exists, if not do an ajax to myapi.com/user/get_loggedin_user and check if logged in before responding with null. One problem here is, ajax is annoying like this, you would then need to put in a success callback function and have all your code execute inside the success callback.

Now lets say im on the Angular App (website), mydomain.com/user/dashboard (already logged in), and then i refresh my browser. Now, when the page reloads, angular does not know my current user, so before it redirects me to mydomain/login, i want it to check if the user is logged in. i can obviously do a 1 time call within the controller, but is there a more easy way where i can register within a controller with some access restrictions (Eg: logged_in == true), and when you visit any page with logged in requirement, it checks local user (gets the user if does not exist), and redirects to login page if null, or display the page once it matches the requirements?

Different common page requirements: null, logged_in, admin, function: haveAccess(user, object).

NOTE: im using stateProvider

3 Answers 3

4

If I understood your question correctly, you are asking about how to check whether the user is logged in before the controller is invoked, and to avoid the check for a logged-in status in each controller that needs it.

If so, you should look into the resolve parameter - this exists both in $routerProvider and $stateProvide.

Essentially you could "resolve" your loggedInUser variable (by doing whatever you need to do via your MyAuth service.

Here's an example of what I mean with $routeProvider:

$routeProvider
   .when("/someSecuredContent", {
     templateUrl: 'someSecuredContent.html',
     controller: 'SecuredController',
     resolve: {
        loggedInUser: function(MyAuth){
           return MyAuth.loggedIn(); // MyAuth.loggedIn() should return a $q promise
        }
     }
});

Then in the controller, loggedInUser will be injected.

Here's a site with more examples.

Sign up to request clarification or add additional context in comments.

7 Comments

This is great (tested and working great). however i have 2 issues with it. 1. every state/substate that needs to be behind authentication layer (user must be logged in), i need to copy paste this ressolve code block (its easy enough, but seems a bit repetitive, must be a better way?). But thats fine, it works, and not big deal if i need to copy paste few lines of code. 2. is there a way to have this trigger globally on every state? This is so i can trigger the MyAuth.getInfo() or MyAPI.getInfo() to get the init info for the app (mainly for first time users entering of refreshing page).
If you want to be fancy with how you load controllers (and their security prerequisites), you should read this useful post, especially towards the end of the section on routeResolver.js file.
@decay, did I answer your question?
Your answer did actually answer the question and seems to be the correct way of doing it. However, it would then need to be copy pasted all over the place. Again, thats not an issue, but is a bit messy. Anyway, i settled with my solution below, where i pass in a AuthRequired flag from the State.Data, and then on change start i check states for such flag, then process it accordingly. To finish it off: (github.com/angular-ui/ui-router/issues/1399). I will however accept your answer as correct, as it is the "correct" way to do it.
I agree that code replication is bad. Like I said, you could gain insights from this blog post about how to avoid that.
|
2

Correct me if im wrong:

Do this within the Main Controller (make sure you inject the dependancies like rootScope, state, and your own Authfactory)

    $rootScope.$on('$stateChangeStart', function (event, next, toParams) {
        if (needToBeLoggedIn()) { //use the next object to read any data, and you can set on the state some flag
            event.preventDefault()
            MyAuth.loggedIn(function success(){ $state.go(next,toParams); }, function err (){/*send somewhere else*/});
        }
    })

Comments

2

Put logged_in = true to cookieStore in your login method after authentication as below.

$cookieStore.put('logged_in',true);
$rootScope.logged_in = true;

and in your Controller, do

$rootScope.logged_in = $cookieStore.get('logged_in');

Now you can use this logged_in variable anywhere in the UI to check if the user is logged in. Make sure to use 'ngCookies' module in your app. and pass the $cookieStore dependency to your controller. You can even keep the user object itself similar to logged_in variable in cookies and retrieve it from cookies. Make sure to do logged_in = false and clear other variables in cookies and set it to blank in your logout method.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.