Pregunta

I have stumbled upon Restangular for making calls to a rest service. It works great and returns a promise. I need to be able to have the call block. The reason for this is on a fresh page reload I am technically not loggged in but I may have a token stored in a cookie. i would like to validate this token against a rest service. Problem is that I need it to block.

If a timeout occurs or if its not valid that i can treat teh user as not authenticated.

This is the reason for wanting to block is that i would like to redirect them using $location.path to a new URL it not a valid token.

This doesn't happen on a specific route so i can't use resolve which is blocking. It technically happens on every route - I use the $on.$routeChangeStart and check an internal variable got LoggedIn or not, if not logged in i check for the stored token.

This happens on each Page refresh but not while navigating inside the application.

The affect I am trying to get is how Gmail works.

Look forward to any insight anyone has on this

Thanks

¿Fue útil?

Solución

Basically you need to ensure that some asynchronous action occurs prior to any route change occurring, and in this case the action is authenticating a user.

What you can do is use the $routeChangeStart event that's emitted in order to add a property to the resolve object on the route like so:

function authenticate() {
    if ( user.isAuthenticated ) {
        return;
    }
    // Just fake it, but in a real app this might be an ajax call or something
    return $timeout(function() {
        user.isAuthenticated = true;
    }, 3000);
}

$rootScope.$on( "$routeChangeStart", function( e, next ) {
    console.log( "$routeChangeStart" );
    next.resolve = angular.extend( next.resolve || {}, {
        __authenticating__: authenticate
    });
});

Since angular will wait for any promises in the resolve object to be fulfilled before proceeding, you can just use a pseudo dependency as in the example. Using something like that, you should be able to guarantee that your user is authenticating prior to any routes successfully executing.

Example: http://jsfiddle.net/hLddM/

Otros consejos

I think the best way to do this might be to push the user around with $location.path, You can use .then() to effectively force a wait by leaving the user on a loading page.

var currentPath = $location.path();

$location.path(loadingScreen);

//Assuming you have some sort of login function for ease.
Restangular.login(token).then(
    function(result) {
        $location.path(currentPath)
    },
    function(error) {
        $location.path(logInScreen)
    }
);

If you're using ui-router, you could move to another state with the same URL, where you'd use that Restangular.login with the then, and in case of success go back to the "logged in" state, otherwise, go to the "log in" state where the user must enter his username and password.

If you're not using ui-router, you could implement something like that with some ng-switch.

So, upon arrival to the screen, you do that Restangular.login and by default you show loading page by setting some boolean to true. Then, if it doesn't succedd, you send him to the login, otherwise, you set loading to false and show page.

Anyway, I'd strongly recommend using ui-router, it rocks :)

Hope this works!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top