Tips for limiting access to certain views in an AngularJS application

I need to restrict users from accessing the /dashboard view and /add-item view, as well as any other views in my AngularJS application.

Here is my router configuration:

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',
            })
        });

Once a user logs in, I store their token in local storage. My goal is to prevent access to any view if the token is not present.

This is my login controller code snippet:

$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");
        });
    }
    }

In case of a 401 error, I redirect the user back to the login page using this interceptor:

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 a user tries to directly access /add-item through the URL, the page briefly opens before closing due to a server-side 401 error, redirecting them to the login page. I want to prevent any unauthorized views from opening without a successful login. As a newcomer to AngularJS, I'm seeking guidance on how to achieve this. Please assist.

Answer ā„–1

If the token is not present, you can save the user's location to bring them back to the same page after they have logged in. You can refer to the code snippet below from 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');
        });

To update the default redirect path, change `$urlRouterProvider.otherwise('login')` to `$urlRouterProvider.otherwise('app/dashboard') in app.config. If it remains as `$urlRouterProvider.otherwise('login')`, the user will be redirected to the login page if a token is present.

 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 them back to the same page after they have logged in */
                    $rootScope.savedLocation = $location.url();

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

Answer ā„–2

To ensure seamless navigation in your application, make sure to include resolve in your route configuration. Here's an example:

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

In the above scenario, if the PostService encounters a 401 error code, indicating an issue, the route controller will not be initialized, preventing access to the view. However, with this setup, your interceptor will still handle the redirect to the login page smoothly without any disruption to the user experience.

Implementing this approach will not only address your current problem but also help mitigate potential issues in the future.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Modifying Class Background Image with AngularJS

I have a class called "tp-cont" that is loaded from a separate .css file. I was able to update the background image using jQuery with the following code. HTML: <li ng-click="changeTemplateBackgroundImage()"></li> Controller: $scope.changeTe ...

Enhance Page Content Dynamically with Symfony2 and Ajax-Like Functionality

When assessing an ArrayCollection in my Template, I am currently using the following loop: {% for article in articles %} <li {% if article.new %} class="new" {% endif %} >{{ article.name|e }}</li> {% endfor %} My go ...

What is the best way to initiate a change event using JavaScript?

I am attempting to enable my 4th checkbox automatically when there is a new value in the textbox (myinput). If the textbox is empty, I want to disable it. Currently, you have to tab out before the change event is triggered. Also, how can I check for an e ...

I am searching for a way to apply a conditional class to the chosen element in react, as the toggle method does not

I'm working on customizing a dropdown menu and I want to add a functionality where if a parent li menu has an arrow class before the ul element, then clicking on that parent li menu will add a class called showMenu only to that specific sub-menu. Her ...

Step-by-step guide on integrating Bulma page loader extension as a Vue component

Is there a way to integrate the Bulma-extension page-loader element as a Vue component in my project? I attempted to import page-loader.min.js and use it, but unfortunately, it didn't work as expected. <template> <div class="steps"> ...

The output in the window will display the result of doubling the input box value, not the div

Can someone help me figure out why my code isn't working as expected? I'm trying to create a text box where you can enter a number, click a button, and it will multiply the number by two and display the result. However, right now, the code opens ...

AngularJS: The total is the accumulation of all corresponding objects

In my project, Iā€™m dealing with an array of Requests that each contain an array of tasks. The goal is to update the duration field of each Request based on the sum of durations of its associated tasks and ensure that these changes are responsive to any u ...

Does Three.js lighting adjust according to the bundler used?

Today, I decided to streamline my portfolio project by transitioning it from standard HTML to the Vite bundler for easier dependency management. I simply copied and pasted the existing code, making adjustments to the imports since I had been using relative ...

Display a spinning wheel or progress bar while the website is in the process of loading

Looking to construct a treeview using the jquery-treeview plugin but noticing it's quite time-consuming (about 5-7 seconds). I'm interested in adding a spinning wheel or progress bar to indicate loading while the page is processing. Any suggestio ...

There are occasions when the Phaser sprite.kill() function fails to execute

Currently, I am developing games using Phaser and have encountered an issue with the sprite.kill() method. At times, when I invoke sprite.kill(), it appears that Phaser destroys the body for collisions/overlapping, but the visual elements (image and dragg ...

When working with React Native, encountering an issue where passing props using the Map function results in an error stating "undefined is not a function" near the section of code involving the

Hey there! I'm currently facing an issue with fetching data from my Sanity CMS and passing it as props to a child component. Interestingly, the same code worked perfectly on another screen, but here I seem to be encountering an error. Although the dat ...

The value of ng-repeat list in AngularJS does not update when its value is changed by an ajax call

I am completely perplexed. Why doesn't my ng-repeat update when there is an ajax call that changes its value? I have searched through many questions and answers here, but none of them address the issue with the ajax call. Here is the HTML: <div c ...

prerender.io is having compatibility issues with the combination of expressjs and angularjs

I recently configured a server using Express.js: const env = process.env.ENVIRONMENT || 'PRODUCTION'; const port = process.env.PORT || 8080; const express = require('express'); const app = express(); if(env === 'PRODUCTION') ...

The canvas doesn't seem to be rotating even after executing the setTransform

Within my HTML5 canvas, I have been experimenting with drawing lines and rotating them around the center point. My goal is to reset the canvas's transformation each time I draw, followed by re-translating/rotating the canvas. However, I have encounter ...

AngularJS uses double curly braces, also known as Mustache notation, to display

I'm currently working on a project where I need to display an unordered list populated from a JSON endpoint. Although I am able to fetch the dictionary correctly from the endpoint, I seem to be facing issues with mustache notation as it's renderi ...

Using JavaScript and jQuery to make calls to the Web API

I am struggling with Java-script callback due to lack of experience. Can anyone provide assistance in resolving the issues I am facing with the code? My goal is to perform a callback from a .json file and search it by ID. While I can display all customers, ...

What is the best way to send the entire image to an API route in Next.js so that I can save it using FS and then upload it to Cloudinary?

I have a form here that utilizes React Hook Form. I'm wondering what I need to pass to the API endpoint via fetch in order to write an image to disk using fs, retrieve its location, and then send that location to Cloudinary. In the body of the fetch ...

Turning Node.js timestamp into MySQL format

Currently, I am using Node (Express.js) to update a MySQL database with the current date. While it is functional, my code seems to be repetitive. let newDate = new Date(); let yearNow = newDate.getFullYear(); let monthNow = newDate.getMonth(); let dayNow ...

The gradual vanishing of principles

Below you will find text fields that I am populating with values that are later utilized in a JavaScript function. These fields are all contained within a form. The issue I am encountering is that when I submit the form, I initially get the correct value ...

Instructions on creating a number increment animation resembling Twitter's post engagement counter

I've been attempting to replicate the animation seen on Twitter's post like counter (the flipping numbers effect that happens when you like a post). Despite my best efforts, I can't seem to make it work. Here is what I have tried: $(fun ...