简体   繁体   中英

how to restrict view in angularjs application

I want to restrict user's to access /dashboard view and /add-item view or any other view in my angular js application.

this is my router

app.config(function($stateProvider, $urlRouterProvider){

        $urlRouterProvider.otherwise('login');

        $stateProvider.
            state('app.dashboard', {
                url: '/dashboard',
                templateUrl: appHelper.viewsPath('dashboard/views/dashboard'),
                controller: 'DashBoardController as DashBordCtrl',
     }).

            // Add Item
            state('app.add-item', {
                url: '/add-item',
                templateUrl: appHelper.viewsPath('item/views/add-item'),
                controller: 'ItemController as ItemCtrl',
            })
        });

After login I am storing the token in my local storage. I want user to not access any view if token is not present.

this is my login controller

$scope.register = function(credentials){
       LoginService.post(credentials,function(success){
           $state.go('app.add-item');
          SessionService.set("token",success.accessToken);


             },function(error){
       FlashService.showError("Please Enter Valid Email Password");
        });
    }
    }

On 401 error i am redirecting to login page like this:

app.config(function ($httpProvider) {
   // $http.defaults.headers.common.Authorization = '';
     delete $httpProvider.defaults.headers.common['X-Requested-With'];

    $httpProvider.interceptors.push(function ($location, $q, SessionService, FlashService) {
        return {
            request: function (config) {
                 config.headers = config.headers || {};
                config.headers.Authorization = SessionService.get('token');
                return config;
            },
            responseError: function (response) {
                if (response.status === 401) {
                   SessionService.unset('token');
                    $location.path('/login');
                }
                return $q.reject(response);
            }
        };
    });
});

But if I type /add-item in url, my add-item page is opening and then it suddenly close,because server return 401 ,and login page appear.I don't want to open any view if user is not login.

I am new in angularjs and i am confusing how to do this. Please help.

If token is not present,You can save the user's location to take him back to the same page after he has logged-in.You can review following code in app.js:

app.config(function($stateProvider, $urlRouterProvider){    

        $stateProvider.
            state('app.dashboard', {
                url: '/dashboard',
                templateUrl: appHelper.viewsPath('dashboard/views/dashboard'),
                controller: 'DashBoardController as DashBordCtrl',
     }).

            // Add Item
            state('app.add-item', {
                url: '/add-item',
                templateUrl: appHelper.viewsPath('item/views/add-item'),
                controller: 'ItemController as ItemCtrl',
            })
 $urlRouterProvider.otherwise('login');
        });

$urlRouterProvider.otherwise('login') replace with $urlRouterProvider.otherwise('app/dashboard') in app.config.if it is $urlRouterProvider.otherwise('login') ,you have a token ,throw login page still.

 app.config(function ($httpProvider) {
       // $http.defaults.headers.common.Authorization = '';
         delete $httpProvider.defaults.headers.common['X-Requested-With'];

        $httpProvider.interceptors.push(function ($location, $q, SessionService, FlashService) {
            return {
                request: function (config) {
                     config.headers = config.headers || {};
                    config.headers.Authorization = SessionService.get('token');
                    return config;
                },
                responseError: function (response) {
                    if (response.status === 401) {
                       SessionService.unset('token');
                        $location.path('/login');
                    }
                    return $q.reject(response);
                }
     if (!SessionService.get('token');) {
                    /* You can save the user's location to take him back to                 the same page after he has logged-in */
                    $rootScope.savedLocation = $location.url();

                    $location.path('/login');
                }
            };
        });
    });

You should use resolve in your route configuration. Example:

state('app.add-item', {
            url: '/add-item',
            templateUrl: appHelper.viewsPath('item/views/add-item'),
            controller: 'ItemController as ItemCtrl',
            resolve: ['SomeService', function(SomeService) {
                return SomeService.getDataFromApi();
            }]
        })

Looking at this example, if SomeService returns 401, meaning an error, that route controller will never instantiate and therefor you cannot access the view. Your interceptor will still do his job, and redirect to login when 401 happens, but now it will happen smoothly and with no flash of the view.

This is a good way to do, and it will solve that problem of yours and also some others you might encounter later.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM