$state.go not executing inside controller - angularjs

I'm trying to redirect a user to a login page if they are not currently logged in:
var user = Session.checkSession();
if(user){
$scope.session.user = user;
} else {
// redirect to login page
$state.go('access.signin');
}
$state is injected into this controller correctly, because if I put dummy.state instead of access.signin I get the error:
Error: Could not resolve 'dummy.state' from state ''
$state.go('access.signin') is used successfully elsewhere in the app, so doesn't look like there's anything wrong with the route. What am I doing wrong here?

Related

Redirect to 404 if unauthorized angular

I am using the rootscope event in run function to check for entitlements like so
$rootScope.$on('$routeChangeStart', function() {
$http.get('auth/urlentitlementcheck').then(function(response) {
if (!response) {
$state.go('app.unauth');
}
});
});
But the problem is my controller functions are still getting called before this redirect happens.Is there another way to check for entitlement so that is happens before anything is called or loaded or am i doing something wrong?

Browser back button going to application page after logout

I have logout button in my angularjs(1.5) application. On click of it calling the login page url.After logout, when i click the browser back button again it is going to my application page instead of login page.
$scope.logOutUser = function () {
$window.location.href = "logoutURL";
}
Can anyone suggest how to implement this in angularjs?
Use $location service's .replace() method
$scope.logOutUser = function () {
$window.location.href = "logoutURL";
$location.replace()
}
Please take this my old post abut the back button issue : How to detect if a user clicks browser back button in Angularjs
You may may need that logic like
$scope.$on('$routeChangeStart', function (scope, next, current) {
if (next.$$route.controller != "Your dashboard Controller Name") {// please be mine dash board controller is your home page after login
// Show here for your model, and do what you need**
$window.location.href = "logoutURL";
}
});
But if you did logout in dashboard page then it would be an issue. At this time you need to maintain a flag with ng-Storage for the user is currently authenticate or not.

How can i redirect to another page without loading the current page in angularjs

I want to redirect to another page without loading the currentpage.
let me explain my task. I am having user login condition.
If the user has not login and he tries to enter the URL directly EX("localhost/sample.html") means it will come to login page. For me this condition is working nicely.
First sample.html page open and then only it will redirect to login. The user able to see the Data in sample.html.
var logincheck = function () {
debugger;
$http.get('loggedin').success(function (user) {
alert(user);
// Authenticated
if (user != '0') {
refresh();
return;
}
// Not Authenticated
else {
$window.location.href = '/';
}
});
};
logincheck();
Is there any way to go login page without loading the sample.html page.
A interesting way do to this is by checking this condition in a $route event. For example, you can write this code in your app.run:
$rootScope.$on('$routeChangeStart', function(event, next, current) {
if(next.$$route && userNotAuthenticated) {
$location.href('/');
}
});
The advantage is that it will work for your whole app, you won't have to write code for each page.
In your main controller (the one attached to index) you should do a login check and set a variable to true/false. In your controller do a check on this variable, and do a $state.go() if user is not logged in.
Use ng-cloak directive in your index file where you attach your main controller like:
<body ng-controller="mainController" ng-cloak>
You can read up on ng-cloak here
This is how you can do it.
Whenever your angular app is boots, it runs the run function. So attach a location change listener in that function like below
App.run(['$rootScope', '$http', '$urlRouter', function($rootScope, $http, $urlRouter) {
$rootScope.$on('$locationChangeSuccess', function(event) {
event.preventDefault();// prevents the location change
$http({// make a http call to check if user is logged in or not.
url: '/path/to/check/auth',
method: 'post',
data: {}
}).then(function(response){
if(response.data.isUserLoggedIn){//If user is logged in.
$urlRouter.sync();
}else{//user is not logged in
window.location.assign('/login');
}
}, function() {
window.location.assign('/login');
});
});
$urlRouter.listen();
}]);

How to redirect using ajax in angularjs

I want to redirect a user on specific page using ajax call in angularjs. I am able to redirect using below mentioned code but when i again want to redirect user to root page i am unable to do so as the value of $window.location.href+ 'getTechnicianWorkOrder/'+woId is persisting as is:
$scope.getTechnicianWorkOrderFormURL = function(woId){
return $window.location.href + 'getTechnicianWorkOrder/'+woId;
};
Another place where i want to redirect to root page:
$scope.getAssignedListURL = function(){
return $window.location.href;
};
Note: i want to make this redirection work even in offline mode of HTML5 cache-manifest.
Using the $location service.
$location.path('/');
The answer by #prashant-palikhe is the right one, $location.path('/'); is the route to your root path. just use the dependency of $location to your controller like this:
yourapp.controller('YourController', ['$location', function($location) {
...
}
I always use the ui.router for my routes and in there you can add $urlRouterProvider.otherwise('/') for fallback in any unknown state or route.
In some cases you can add something like this in your states:
resolve : {
dataObj : ['$http', function($http) {
return $http({method : 'GET', url : '/your/ajax/endpoint'})
;}],
},
onEnter : ['dataObj', '$state', function(dataObj, $state) {
// dataObj is your ajax response object. Based on this you can redirect to a certain state of needed
$state.go('default');
}]
resolve is data that preloads data onEnter is called before entering the state. This can be used as some sort of middleware.

ui-router StateChange event go through even with redirection

I am developping an OAuth Provider application, using AngularJS and ui-router.
For each state change, I do the following check:
If the user is already logged in:
1.1 If the user is not an admin -> redirect him to the callBackUrl
1.2 If the user is an admin, do nothing
If the user is not logged in:
2.1 If the user tries to access an admin page -> redirect him back to login
2.2 If not, do nothing
my ui-router run method is the following:
.run(function ($rootScope, $state, $auth, accountService, $window, $stateParams) {
$rootScope.$on('$stateChangeStart', function (e, toState, toParams, fromState, fromParams) {
accountService.getUser({ token: $auth.getToken() }).$promise
.then(function (response) {
if (response.isAdmin === false) {
e.preventDefault();
$window.location.href = $stateParams.callBackUrl;
return;
}
})
.catch(function (response) {
if (toState.name.split(".")[0] === 'admin') {
e.preventDefault();
$state.go('root.login');
}
});
});
});
Everything is OK except for the part where I redirectthe user to the callback URL using $window
$window.location.href = $stateParams.callBackUrl;
This redirection takes 2-3 seconds, and in the meantime my user can see the page he is trying to access on my application. I thought the use of preventDefault() would solve that but it doesn't. Do you know how I could hold the $statechangeevent so that the user is redirected directly to the callback URL?
Thanks
I would put it this way:
The above approach allows user everything, until he is not really proven to be UN-authenticated. Why that? Because the code is calling service and evaluating all the stuff once the data are received. Meanwhile - we trust the user.
So, I'd suggest to change the approach
NEVER trust the user. He/she must to do the best to prove he/she is the right one, to get somewhere ... (well, kind of that...)
I described one possible way (with working example) here:
Confusing $locationChangeSuccess and $stateChangeStart
Just a piece of code to cite
Th first part of the $rootScope.$on('$stateChangeStart', ...:
// if already authenticated...
var isAuthenticated = userService.isAuthenticated();
// any public action is allowed
var isPublicAction = angular.isObject(toState.data)
&& toState.data.isPublic === true;
// here - user has already proved that he is the one
// or the target is public (e.g. login page)
// let him go, get out of this check
if (isPublicAction || isAuthenticated) {
return;
}
The second part, user is not trusted, he requires access to private stuff
// now - stop everything
// NO navigation
// we have to be sure who user is, to continue
// stop state change
event.preventDefault();
// async load user
userService
.getAuthObject()
.then(function (user) {
var isAuthenticated = user.isAuthenticated === true;
if (isAuthenticated) {
// let's continue, use is allowed
$state.go(toState, toParams)
return;
}
// log on / sign in...
$state.go("login");
})
Check that, in action, here
I know this was asked a while ago, but here is a possible solution:
Ui-router actually provides a fantastic way to solve this. By using a "resolve" within your $stateProvider, you can check that the user is authenticated before the controller of that particular state is even instantiated. Here is what ui-router docs say about resolve:
Resolve
You can use resolve to provide your controller with content or data that is custom to the state. resolve is an optional map of dependencies which should be injected into the controller.
If any of these dependencies are promises, they will be resolved and converted to a value before the controller is instantiated and the $stateChangeSuccess event is fired.
https://github.com/angular-ui/ui-router/wiki - Section for resolve is almost half way down page
You can run accountService.getUser within the resolve to check for an authenticated user, and by doing so, would prevent someone who is not authed from seeing the view they are trying to route to.
The resolve is set up inside the $stateProvider, and may look something like this:
$stateProvider.state('myState', {
resolve: {
userAuth: function(accountService) {
return accountService.getUser();
}
}
)
If you notice in the above example, I set a property called userAuth within the resolve. This can now be injected into any controller or service and then you can check against it for authenticated users. Each state that needs to be a "protected" view can contain the resolve, and then the 2-3 second flash of the view won't occur, as the controller hasn't been instantiated, and the user is redirected to another state.

Resources