Maintaining AngularJS Authentication Securengular: Ensuring

I need to find the ideal architectural solution.

Below is the HTML code I currently have:

<body ng-controller="individualFootprintController as $ctrl">
<div ng-hide="$ctrl.authenticated">
            <h1>Login</h1>
            With Corporate Account: <a href="/login/corporate">click here</a>
</div>

And this is the controller:

function individualFootprintController($http) {
        var self = this;
        $http.get("/is_auth").success(function () {
            self.authenticated = true;
        })
            .error(function() {
                self.authenticated = false;
            }
        );
}

Inquiries:

1) Should this logic be in the controller?

2) How can I get the actual "is_authenticated" value while only making the request once?

Answer №1

In order to authenticate with the backend, it is necessary to have a valid token rather than just toggling a simple flag for authentication. Without including a username/password/cookie/token in the request, access to the backend will be denied.

Storing the token in a controller is not ideal as controllers are not meant to be permanent structures. It is best to store the token in a service where other components can access it as needed.

  1. Authentication status should rely on the presence of a valid authentication token.
  2. The authentication token should be stored in a centralized location, typically a service.
  3. Other services can retrieve the token from this central location to determine if the app is currently authenticated.

An example structure could look like this:

app.service('AuthService', function () {
    this.token = null;
});

app.service('FooService', function (AuthService, $http) {
    $http.get(..., AuthService.token, ...)
});

app.controller('LoginStatusController', function (AuthService) {
    Object.defineProperty(this, 'isLoggedIn', {
        get: function () { return AuthService.token != null; }
    });
});
<div ng-controller="LoginStatusController as ctrl">
    <div ng-hide="ctrl.isLoggedIn">

Upon logging in and receiving a token, set AuthService.token so that all other components can access it. If the token becomes invalid or unset, all authenticated statuses will be revoked.

Answer №2

My typical approach involves the following steps:

Utilizing ui-router

  • Utilizing the resolve hook to inject arguments into the controller and defining subroutes of a main route to check authentication on each route change

    scripts/services/user.js

     angular.module('yourmodule')
      .service('userSrv', function ($http, $q) {
        var srv = {};
    
        srv.getAuthenticatedUser = function() {
          return $http.get("/authenticated_user");
        };
    
        return srv;
      });
    

    scripts/routes.js

    angular
     .module('yourmodule')
     .config(function ($stateProvider) {
       $stateProvider
        .state('authenticated', {
          abstract: true,
          template: '<ui-view />',
          controller: 'AuthenticatedCtrl',
          resolve: {
            signedInUser: function(userSrv, $q) {
              return userSrv.getAuthenticatedUser()
              .then(function(null, function() {
                //Catch any auth error, likely 403
                //And transform it to null "signedInUser"
                //This is the place to handle error (log, display flash)
                return $q.resolve(null);
              });
            }
          }
        })
        .state('authenticated.myspace', {
          url: '/myspace',
          templateUrl: 'views/myspace.html'
        });
     });
    
  • Leveraging $scope inheritance within your view

    scripts/controllers/authenticated.js

     angular.module('yourmodule')
      .controller('AuthenticatedCtrl', function (signedInUser, $scope, $state) {
       //Here you set current user to the scope
       $scope.signedInUser= signedInUser;
    
       $scope.logout = function() {
         //this is where you would put your logout code.
         //$state.go('login');
       };
     });
    

    views/myspace.html

     <!-- here you call parent state controller $scope property -->
     <div ng-hide="signedInUser">
       <h1>Login</h1>
         With Corporate Account: <a href="/login/corporate">click here</a>
     </div>
    

1) How can I get the actual "is_authenticated" value with only one request? By querying for authenticated user on each route change, which may seem unusual but proves to be efficient. The query should not take more than 30ms, as it's a small SELECT operation. However, asking "am I authenticated" and "get the authenticated user" are essentially the same, except one returns a boolean and the other returns the user. It is recommended to handle the "am I authenticated" question by requesting the authenticated user and then converting it to a boolean using "if(user)" (accounting for null values).

2) Is it appropriate to have this logic in the controller? Yes and no. While setting the user to the scope makes sense in the controller, it is advisable to move the HTTP API logic to a service and handle routing events separately in another file.

NB: For complete route protection (such as redirection on non-authenticated access), feel free to ask another question for detailed guidance.

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

Is there a way for me to replace zero with a different number dynamically?

Is there a way to dynamically insert a different number instead of zero in mongoose? displayCity: (req, res, next) => { let id = req.params.id; provinceAndCity.findById({ _id: id }).populate('city.0.limitation', 'title ...

Tips for dynamically loading a modal

Hello, I am curious about dynamically loading modals on different images within my current webpage. For example, when the life of Pi image is clicked, a modal pops up displaying relevant information. I would like this functionality to extend to other ima ...

Incorporating Meteor js into an established user system

I'm completely new to the world of Meteor and I am looking to integrate it with my current system that relies on a MongoDB database. As I explore Meteor, I have discovered that there are packages like accounts-facebook and accounts-twitter which assis ...

Error: The object does not have the property createContext necessary to call React.createContext

I'm currently exploring the new React Context API in my app. I've also implemented flow for type checking. However, when I add // @flow to a file that contains the code: const MyContext = React.createContext() An error pops up stating: Cannot ...

[Vue alert]: Issue in created function: "TypeError: Unable to assign value to undefined property"

I'm currently in the process of developing a VueJS application where I have implemented a child component called Child.vue that receives data from its parent. Child.vue export default{ props:['info'], data: function(){ ...

My app's custom barrel configurations don't appear to be functioning properly in Angular 2's system-config.ts

My system-config.ts file is as follows: 'use strict'; // SystemJS configuration file, for more information visit: // https://github.com/systemjs/systemjs // https://github.com/systemjs/systemjs/blob/master/docs/config-api.md /***************** ...

Leveraging Gatsbyjs to Integrate GraphQL Data with Material UI Library

Just starting out as a Frontend Developer and currently learning Gatsbyjs along with the Material UI library. I'm working on creating a new page using the Material UI Gatsby Starter code available here. However, I've encountered an issue when tr ...

Unexpected results occur when accessing data in $uibModal.open() within Angular JS causing it to

Here is the code snippet that is causing the issue of returning undefined items in AngularJS: App.js code console.log('single page application script is working'); var myApp = angular.module("demoApp", ["ngRoute", 'ui.bootstrap',&apos ...

A guide to transferring modules between component files in JavaScript

My query pertains to the handling of imports in web pages. When a file is imported into another, do the declarations and imports from the imported file become available in the file where it is being imported? A suggestion was made for me to import a compo ...

Unable to switch the text option

[Fiddle] I'm currently working on a project where I want pairs of buttons to toggle text by matching data attributes. While I can successfully change the text from "Add" to "Remove" on click, I am facing an issue with toggling it back to "Add" on the ...

Error: Unexpected token : encountered in jQuery ajax call

When creating a web page that requests remote data (json), using jQuery.ajax works well within the same domain. However, if the request is made from a different domain (e.g. localhost), browsers block it and display: No 'Access-Control-Allow-Or ...

Navigate to the final element of a mapped array

My current project includes a Message component that showcases all messages, whether incoming or outgoing, within a single thread. One feature I am aiming to implement involves ensuring that the most recent message, a freshly typed one, or an incoming mes ...

What is the reason behind console.log() displaying an array, while typeof returning 'object'?

This question pertains to the outcome of a mongoose find() operation. After running the code console.log('apparently this is an ' + typeof campaign.advertGroups, campaign.advertGroups); The resulting output is as follows: apparently this is an ...

Is there a way to reset back to the default CSS styles?

I have a div container with a nested span element (simplified). <div class="divDash"> <span>XX</span> </div> The CSS styling for the div makes the span initially hidden and only visible when hovering over the parent div. .div ...

Integrate Form.io with a SQL Server database

I'm looking for guidance on connecting SQL Server data with form.io. I've already created a basic form in the form.io application and embedded it into my project. Now, I'd like to store the submitted data in an SQL Server database. Any assis ...

What is the reason behind negative numbers appearing as "5-" rather than "-5" in the basic calculator coded using HTML and JavaScript?

As I am practicing my coding skills, I encountered an interesting issue. Any operation that results in a negative number displays as wrong, but when using console.logs it shows the correct result. Can someone explain why this is happening? <!DOCTYPE h ...

Using Vue.js data with an erb link_to tag

Currently, I am developing a Rails application where one page utilizes Vue.js to load a Google map, make some API calls with Axios, and gather user values using Vue.js. My goal is to pass these values as parameters within a "link_to" erb tag. Please refer ...

Is there a way to use JavaScript to rearrange the order of my div elements?

If I have 4 divs with id="div1", "div2", and so on, is there a way to rearrange them to display as 2, 3, 1, 4 using Javascript? I am specifically looking for a solution using Javascript only, as I am a beginner and trying to learn more about it. Please p ...

The methodology of executing a Javascript function

I have the following code snippet: (function() { $(document).ready(function() { //Event handlers $('.project-delete').on('click', function() { deleteProject($(this)); }); $('.keyword-delete').on(&ap ...

Error: Unable to authenticate due to timeout on outgoing request to Azure AD after 3500ms

Identifying the Problem I have implemented SSO Azure AD authentication in my application. It functions correctly when running locally at localhost:3000. However, upon deployment to a K8s cluster within the internal network of a private company, I encounte ...