AngularJs with ui.router how to set authenticate for its children - javascript

i'am using AngularJS with ui-router, this is my current app.js configuration.
'use strict';
angular.module('nodeserverApp', [
'ngCookies',
'ngResource',
'ngSanitize',
'ngRoute',
'ui.bootstrap',
'ui.router'
])
.config(function ($routeProvider, $locationProvider, $httpProvider , $stateProvider , $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: 'partials/user/main',
controller: 'MainCtrl'
})
.state('dashboard', {
url: '/user/dashboard',
templateUrl: 'partials/user/dashboard/main',
controller: 'UserDashboardDashboardCtrl',
authenticate: true
})
.state('dashboard.welcome', {
url: '/welcome',
parent: 'dashboard',
templateUrl: 'partials/user/dashboard/welcome'
})
.state('dashboard.account', {
url: '/account',
templateUrl: 'partials/user/dashboard/account',
controller: 'UserDashboardAccountCtrl'
})
.state('dashboard.address', {
url: '/address',
templateUrl: 'partials/user/dashboard/address/index'
})
.state('dashboard.address.view', {
url: '/view',
templateUrl: 'partials/user/dashboard/address/view',
controller: 'UserDashboardAddressViewCtrl'
})
.state('dashboard.address.new', {
url: '/new',
templateUrl: 'partials/user/dashboard/address/new',
controller: 'UserDashboardAddressNewCtrl'
})
.state('login', {
url: '/user/login',
templateUrl: 'partials/user/login',
controller: 'LoginCtrl'
})
.state('signup', {
url: '/user/signup',
templateUrl: 'partials/user/signup',
controller: 'SignupCtrl'
})
.state('settings', {
url: '/user/settings',
templateUrl: 'partials/user/settings',
controller: 'SettingsCtrl',
authenticate: true
});
$urlRouterProvider.otherwise("/");
$locationProvider.html5Mode(true);
// Intercept 401s and 403s and redirect you to login
$httpProvider.interceptors.push(['$q', '$location', function($q, $location) {
return {
'responseError': function(response) {
if(response.status === 401 || response.status === 403) {
$location.path('/user/login');
return $q.reject(response);
}
else {
return $q.reject(response);
}
}
};
}]);
})
.run(function ($rootScope, $state, Auth) {
$rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams){
if (toState.authenticate && !Auth.isLoggedIn()){
// User isn’t authenticated
$state.transitionTo("login");
event.preventDefault();
}
});
});
as you can see, dashboard requires authentication, how can i make it's children inherit the authenticate like dashboard.welcome , dashboard.address.view etc. with out the need to specify each one?

I know this is pretty old, but for future Googlers, note that the data property is inherited by child states, so you can place something like this authenticate flag in the parent. These modifications to your should do the trick:
For $stateProvider:
.state('dashboard', {
url: '/user/dashboard',
templateUrl: 'partials/user/dashboard/main',
controller: 'UserDashboardDashboardCtrl',
data: {
authenticate: true
}
})
For angular.module:
.run(function ($rootScope, $state, Auth) {
$rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams){
if (toState.data.authenticate && !Auth.isLoggedIn()){
// User isn’t authenticated
$state.transitionTo("login");
event.preventDefault();
}
});
});

I hope this link will help, this is a great article from Frederik Nakstad about the Single Page Auth for AngularJS, sorry but not able to provide you the detail codes
http://frederiknakstad.com/2013/01/21/authentication-in-single-page-applications-with-angular-js/

Related

Building $routeProvider based on Role

I have a very simple requirement.
I have 3 User Roles:
CATUSER
LICUSER
ALLUSER
I have the value of the User Role in the $rootScope.userRole variable.
I have the User Role already defined before the AngularJS application starts because AngularJS app is called from a PHP script and User Role is already defined in the PHP script.
Now, when the AngularJS app starts, according to the Role I want to have following Routes:
$rootScope.userRole == "CATUSER"
if ($rootScope.userRole == "CATUSER") {
$routeProvider
.when("/catheter", {
title: "Catheter Expiration Code Generator",
templateUrl: "app/catheter/catheter.html",
controller: "CatheterController",
controllerAs: "vm"
})
.when("/support", {
title: "Support",
templateUrl: "app/support/support.html",
controller: "SupportController",
controllerAs: "vm"
})
.otherwise({
redirectTo: "/catheter"
});
}
$rootScope.userRole == "LICUSER"
if ($rootScope.userRole == "LICUSER") {
$routeProvider
.when("/license", {
title: "License Generator",
templateUrl: "app/license/license.html",
controller: "LicenseController",
controllerAs: "vm"
})
.when("/support", {
title: "Support",
templateUrl: "app/support/support.html",
controller: "SupportController",
controllerAs: "vm"
})
.otherwise({
redirectTo: "/license"
});
}
$rootScope.userRole == "ALLUSER"
if ($rootScope.userRole == "LICUSER") {
$routeProvider
.when("/license", {
title: "License Generator",
templateUrl: "app/license/license.html",
controller: "LicenseController",
controllerAs: "vm"
})
.when("/catheter", {
title: "Catheter Expiration Code Generator",
templateUrl: "app/catheter/catheter.html",
controller: "CatheterController",
controllerAs: "vm"
})
.when("/support", {
title: "Support",
templateUrl: "app/support/support.html",
controller: "SupportController",
controllerAs: "vm"
})
.otherwise({
redirectTo: "/license"
});
}
I don't want to use UI Router.
I use UI Router for this kind of purpose in past.
Here is the sample code to get you started
angular
.module('app', [
])
.config(function ($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider
.state('license', {
url: 'url',
templateUrl: './preview.html',
controller: 'LicenseController',
data: {
requiredAuth: true,
role: ['CATUSER', 'LICUSER'],
permission : ['read', 'write', 'etc etc']
}
})
$urlRouterProvider.otherwise(subdomain1 + 'error');
})
.run(['$rootScope', '$state', function ($rootScope, $state) {
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
// is authenticated
var isAuthenticationRequired = toState.data
&& toState.data.requiredAuth
&& !AuthService.isAuthenticated() //some service to check if user is authenticated (I use localstorage lookup here)
;
// is authorized
var isAuthorizationRequired = toState.data
&& (toState.data.role && AuthService.IsInRole(toState.data.role))
&& (toState.data.permission && AuthService.IsInPermission(toState.data.permission))
;
if (isAuthenticationRequired) {
event.preventDefault();
$state.go('auth.login');
}
else if (isAuthorizationRequired) {
event.preventDefault();
$state.go('auth.denied');
}
});
$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams, error) {
cfpLoadingBar.complete();
});
$rootScope.$on('$stateChangeError', function (event, toState, toParams, fromState, fromParams, error) {
cfpLoadingBar.complete();
});
}]);
Here you see License route has property data. Its required authentication and it is authorized for LICUSER and CATUSER roles. You can also add more permission check here for example read, write etc. If user is authenticated and authorized the requested the requested state will load up else will redirect to login or denied request.

State routes back to previous page even after login

After refreshing the page, the state changes back to login. I am using $sessionStorage to store the data and I am able to print them successfully after login, but when I refresh the page, my page should stay on dashboard.html but routes to login state.
angular.module('App', [
'ngAnimate',
'ngCookies',
'ngResource',
'ngSanitize',
'ngAnimate',
'ngTouch',
'ui.bootstrap',
'ui.router',
'toaster',
'ngStorage'
])
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('login', {
url: '/login',
templateUrl: "views/login.html"
})
.state('dashboard', {
url: '/dashboard',
templateUrl: "views/dashboard.html",
required: true
});
$urlRouterProvider.otherwise('/login');
})
.run(["$rootScope", "$state", "$location", "authService", "$cookies", "$sessionStorage", function ($rootscope, $state, $location, authService, $cookies, $sessionStorage) {
$rootscope.$on('$stateChangeStart', function (e, toState, toParams, fromState, fromParams) {
if (toState.required && !$sessionStorage.authuserid) {
alert("state not authenticated");
e.preventDefault();
$state.go('login');
}
});
}]);
Here is my controller:
angular.module('App')
.controller('loginController', ['$scope', '$http', '$timeout', '$location', '$rootScope', 'AUTHEVENTS', 'authService', '$cookies', '$state', 'userManagementFactory', '$localStorage', '$sessionStorage', function ($scope, $http, $timeout, $location, $rootScope, AUTHEVENTS, authService, $cookies, $state, userManagementFactory, $localStorage, $sessionStorage) {
$scope.login = function () {
authService.login(data).then(function (response) {
$rootScope.$broadcast(AUTHEVENTS.loginSuccess);
console.log("response data is: ", response);
$sessionStorage.auth = response;
$sessionStorage.authname = response.data.name;
$sessionStorage.authrole = response.data.roles[0].name;
$sessionStorage.authuserid = response.data.user_id;
$sessionStorage.authprofilepic = response.data.profile_picture;
if ($sessionStorage.authuserid) {
$state.go('dashboard');
} else {
alert('user not authenticated');
}
}, function (error) {
$scope.responseMessage = error.data.error;
$rootScope.$broadcast(AUTHEVENTS.loginFailed);
}
)
}
}])
Html:
<div ng-controller="loginController">
<header class="main-header" ng-include src="'views/header.html'"></header><!--/main top header -->
<div ui-view></div>
</div>
I am not sure what is causing it to change route on page refresh?
StateConfig doesnt seem to accept 'required' field, please refer https://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$stateProvider
Instead you should have
.state('dashboard', {
url: '/dashboard',
templateUrl: "views/dashboard.html",
data: {
required: true
}
});
and should check like this.
if (toState.data && toState.data.required && !$sessionStorage.authuserid) {
Try moving $urlRouterProvider.otherwise('/login'); before
`$stateProvider
.state('login', {
url: '/login',
templateUrl: "views/login.html"
})
.state('dashboard', {
url: '/dashboard',
templateUrl: "views/dashboard.html",
required: true
});`

angularjs - backspace is not working

I have a problem when i click on backspace
it doesn't go to the last page
i don't know how to fix it sometime it does go the last page only when i go from app.home page to app.newJob.Step1 and press backspace it goes back to home but not always
here is my router
'use strict';
angular.module('ijob').
config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'Views/login.html',
data: {
requireLogin: false
}
})
.state('app', {
abstract: true,
template: '<ui-view/>',
data: {
requireLogin: true
}
})
.state('app.home', {
url: '/home',
templateUrl: '/Views/home.html'
})
.state('app.editJob', {
url: '/editJob',
templateUrl: 'Views/editJob.html'
})
.state('app.purchasePackages', {
url: '/purchasePackages',
templateUrl: 'Views/purchasePackages.html'
})
.state('app.accountDetails', {
url: '/accountDetails',
templateUrl: 'Views/accountDetails.html'
})
.state('app.jobOrder2', {
url: '/jobOrder2',
templateUrl: 'Views/jobOrder2.html'
})
.state('app.newJob', {
abstract: true,
templateUrl: 'Views/newJob/newJob.html',
url: '/newJob'
})
.state('app.newJob.Step1', {
url: '/newJob/step1',
templateUrl: 'Views/newJob/step1.html'
})
.state('app.newJob.Step2', {
url: '/newJob/step2',
templateUrl: 'Views/newJob/step2.html'
})
.state('app.newJob.Step3', {
url: '/newJob/step3',
templateUrl: 'Views/newJob/step3.html'
})
.state('app.newJob.Step4', {
url: '/newJob/step4',
templateUrl: 'Views/newJob/step4.html'
})
.state('app.newJob.Step5', {
url: '/newJob/step5',
templateUrl: 'Views/newJob/step5.html'
});
$urlRouterProvider.otherwise('/home');
// $locationProvider.html5Mode(true);
})
.config(function config() {
});
and my app
'use strict';
// Declare app level module which depends on views, and components
angular.module('ijob', [
'ui.router', 'ngRoute', 'btorfs.multiselect', 'ngCookies', 'ngResource'
]);
var app = angular.module('ijob');
app.run(['$state', '$cookieStore', '$rootScope', 'Auth', 'UserService',
function ($state, $cookieStore, $rootScope, auth, userService) {
$rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
var requireLogin = toState.data.requireLogin;
if (requireLogin && !($cookieStore.get('authdata'))) {
event.preventDefault();
$state.go('login');
}
else if ($cookieStore.get('authdata') && $state.current.name !== toState.name) {
userService.token = auth.getCredentials($cookieStore.get('authdata'));
console.log(userService);
$state.current.name = toState.name;
$state.go(toState.name);
}
});
}]);
sometimes i get that error
Error: No such state 'app.newJob.Step1'
or
Error: No such state 'login'
and the states do exist.
its something about the ui router?
or there is anyway to override that?

Possible to dynamically load controllers in Angular

When I go to a specific view in my Angular project, every controller code is being load.
I understand that it's possible to prevent this. But is it possible in the following situation?
App.js config:
app.config(['$stateProvider', '$urlRouterProvider', '$httpProvider',
function($stateProvider, $urlRouterProvider, $httpProvider, $locationProvider) {
$httpProvider.interceptors.push('AuthInterceptor');
$stateProvider.state('home', {
url: "/home",
templateUrl: 'views/Home.html',
controller: "MainController",
onEnter: ['$state', 'auth', function($state, auth) {
if (auth.isLoggedIn()) {
$state.go('challenge');
}
}]
}).state('login', {
url: '/login',
templateUrl: 'views/Login.html',
controller: 'UserCtrl',
onEnter: ['$state', 'auth', function($state, auth) {
if (auth.isLoggedIn()) {
$state.go('home');
} else {
//console.log("Niet ingelogd")
}
}]
}).state('register', {
url: '/register',
templateUrl: 'views/Register.html',
controller: 'UserCtrl',
onEnter: ['$state', 'auth', function($state, auth) {
if (auth.isLoggedIn()) {
$state.go('home');
}
}]
}).state('challenge', {
url: '/challenges',
templateUrl: 'views/Challenges.html',
controller: 'ChallengeCtrl',
onEnter: ['$state', 'auth', function($state, auth) {
if (!auth.isLoggedIn()) {
$state.go('login');
}
}]
}).state('profile', {
url: '/profile',
templateUrl: 'views/Profile.html',
controller: "ProfileCtrl",
onEnter: ['$state', 'auth', function($state, auth) {
if (!auth.isLoggedIn()) {
$state.go('login');
}
}]
}).state('policy', {
url: '/policy',
templateUrl: 'views/Policy.html',
controller: 'AppCtrl'
}).state('cookie', {
url: '/cookie',
templateUrl: 'views/Cookie.html',
controller: 'AppCtrl'
}).state('challengesdone', {
url: '/challengesdone',
templateUrl: 'views/Challengesdone.html',
controller: 'ChallengesDoneCtrl',
onEnter: ['$state', 'auth', function($state, auth) {
if (!auth.isLoggedIn()) {
$state.go('login');
}
}]
}).state('forgot', {
url: '/forgot',
templateUrl: 'views/Forgot.html',
controller: 'UserCtrl'
}).state('reset', {
url: '/reset?sptoken',
templateUrl: 'views/Reset.html',
controller: 'UserCtrl'
});
$urlRouterProvider.otherwise('home');
}]);
Can this be accomplished without the use of external libraries and are there alot of adjustments needed?
You need to use $controllerProvider in your config.
app._controller = app.controller
app.controller = function (name, constructor){
$controllerProvider.register(name, constructor);
return (this);
};
And then resolve this method in your route.
.state('reset', {
url: '/reset?sptoken',
controller: 'UserCtrl',
resolve: {
deps : function ($q, $rootScope) {
var deferred = $q.defer();
require(["js/userCtrl"], function (tt) {
$rootScope.$apply(function () {
deferred.resolve();
});
deferred.resolve()
});
return deferred.promise;
}
},
templateUrl: 'views/Reset.html'
});
I have put together a CodePen for your.

Sails app using angular-ui-router fails to load state based views

I'm attempting to use angular-ui-router to display templates, based on state. Currently, i'm not getting errors in the terminal. In the console, I see "Uncaught TypeError: Cannot read property 'isDefined' of undefined" and "uncaught TypeError: Cannot read property 'isDefined' of undefined". This makes me think I'm not instantiating modules properly. New to angularjs and hoping someone might be able to point me in the right direction. app.js
var app = angular.module('app', ['ui.bootstrap', 'ui.router', 'ngMessages', 'app-templates'])
.run(function($rootScope, $state, Auth) {
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
if (!Auth.authorize(toState.data.access)) {
event.preventDefault();
$state.go('anon.login');
}
});
});
And, routes.js.
angular.module('app')
.config(function($stateProvider, $urlRouterProvider, AccessLevels) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('anon', {
abstract: true,
template: '<ui-view/>',
data: {
access: AccessLevels.anon
}
})
.state('anon.index', {
url: '/',
templateUrl: 'index.html'
})
.state('anon.login', {
url: '/login',
template: 'auth/login.html',
controller: 'LoginController'
})
.state('anon.register', {
url: '/register',
templateUrl: 'auth/register.html',
controller: 'RegisterController'
});
$stateProvider
.state('user', {
abstract: true,
template: '<ui-view/>',
data: {
access: AccessLevels.user
}
})
.state('user.messages', {
url: '/messages',
template: 'user/messages.html',
controller: 'MessagesController'
});
});

Categories