angularjs-auth

0.0.12 • Public • Published

AngularJS Authentication

Secure your app with this module. It works great with Grails server-side apps using Spring Security Core and Spring Security Rest plugins.

Dependencies

It depends on ui-router and angular-storage. Make sure you're using these dependencies on your app.

Installing

To install this module, run the following:

Npm:

npm install angularjs-auth --save

Bower:

bower install willcrisis-angularjs-auth --save

After installing, add a reference to this module to your app.js:

angular.module('myModule', ['willcrisis.angularjs-auth']);

Configuring

This plugin has some configuration that you can customize using authConf provider:

angular.module('myModule').config(function(authConfProvider) {
  authConfProvider.default.endpointUrl = 'http://myServer/myLoginEndpoint';
  authConfProvider.default.logoutEndpointUrl = 'http://myServer/myLogoutEndpoint';
  authConfProvider.default.loginState = 'myLoginState';
  authConfProvider.default.usernameFormProperty = 'username';
  authConfProvider.default.passwordFormProperty = 'password';
  authConfProvider.default.usernameProperty = 'username';
  authConfProvider.default.tokenProperty = 'token';
  authConfProvider.default.rolesProperty = 'roles';
  authConfProvider.default.refreshTokenProperty = 'refresh_token';
  authConfProvider.default.tokenTypeProperty = 'token_type';
  authConfProvider.default.adminRole: 'ROLE_ADMIN';
  authConfProvider.default.functionIfDenied = function(stateService, toState) {
    //what to do if user can't access this state
  };
  authConfProvider.default.functionIfAuthenticated = function(authService, responseData) {
    //what to do if user is successfully authenticated
  };
  authConfProvider.default.setFunctionIfLoggedOff = function() {
    //what to do if user is successfully logged off
  };
});

//if you need to use some services that can't be accessed in .config() phase, you can use .run():
angular.module('myModule').run(function(myService, authConf) {
  authConf.default.functionIfLoggedOff = function() {
    myService.doSomething();
  };
}

endpointUrl (required)

Sets the server login URL. Ex.: 'http://localhost:8080/login'

logoutEndpointUrl(optional, default: null)

If you need logout the user on server side, set the logout endpoint here. If you're not using server-side logout, just ignore this option.

loginState (optional, default: 'login')

After creating the login state using angular-ui-router, set the state name here.

usernameFormProperty (optional, default: 'username')

Property name that will be sent in HTTP request containing username value.

passwordFormProperty (optional, default: 'password')

Property name that will be sent in HTTP request containing password value.

usernameProperty (optional, default: 'username')

Property name that contains username on login HTTP response.

tokenProperty (optional, default: 'access_token')

Property name that contains access token on login HTTP response.

rolesProperty (optional, default: 'roles')

Property name that contains user roles on login HTTP response.

refreshTokenProperty (optional, default: 'refresh_token')

Property name that contains the refresh token on login HTTP response.

tokenTypeProperty (optional, default: 'token_type')

Property name that contains token type on login HTTP response. Ex. 'Bearer', etc.

adminRole (optional, default: 'ROLE_ADMIN')

Name of the role that identify an admin user. If a user contains this role, it will have full access to all states.

functionIfDenied(stateService, toState, authConf, authService) (optional, default: redirect to login page)

Function to execute if user can't access the destination state. The $state service is passed as a param, so you can use it even on .config() block of your module.

functionIfAuthenticated(authService, responseData) (optional, default: do nothing)

Function to execute if user is successfully authenticated. The auth service and server response data are passed as parameters to the function. Use this if you want, for example, set custom HTTP headers further than user's token.

functionIfLoggedOff() (optional, default: do nothing):

Function to execute if user is successfully logged off. Use this if you want, for example, clear custom HTTP headers further than user's token.

Securing your states

When defining your states using angular-ui-router, you can define some properties to make this module work just like this:

angular.module('myModule').config(function($stateProvider, authConf) {
  $stateProvider.state('stateName', {
    url: '/myState',
    templateUrl: 'myTemplateUrl',
    controller: 'MyController',
    auth: ['ROLE_USER', 'ROLE_CUSTOM'],
    requireAll: true
  });
}

auth (optional)

If you don't want to secure the state, i.e., any user would be able to access it, you should not set auth property. If you want to secure the state, define auth property in it. The following values are valid:

auth: true

When using auth: true, angularjs-auth will only allow logged in users to access the state.

auth: false

When using auth: false, angularjs-auth will not allow logged in users to access the state.

auth: ['ROLE_ARRAY']

When using auth: ['ROLE_ARRAY'], angularjs-auth will only allow logged in users that has any of the roles defined in array, except if it has the adminRole. In that case, it will have full access to all states. If you want to allow access only to users that have all the specified roles, you must set requireAll property to true.

Logging in your users

To login your users, you can use auth service in your controller. It will fire a POST HTTP request to the login endpoint configured in authConf.

angular.module('myModule').controller('LoginController', function($scope, auth) {
    $scope.login = function() {
        auth.login($scope.username, $scope.password).then(function(loggedInUser) {
            //Do something
        }).catch(function(error) {
            console.error('Something went wrong.', error);
            //Do something
        });
    };
});

auth

Service contains following properties and functions:

auth.username (String)

Returns logged in user's username.

auth.roles (Array)

Returns logged in user's roles.

auth.token (String)

Returns logged in user's token.

auth.refreshToken (String)

Returns logged in user's refresh token.

auth.tokenType (String)

Returns logged in user's token type.

auth.loggedIn (boolean)

Returns true if the user is logged in, otherwise returns false.

auth.customProperties (object)

Allows defining custom data to this service. Use this to store user's name, for example.'

auth.broadcast()

Broadcasts the login change state. It will fire 'stateChange' event.

auth.login(username, password, endpointName(optional))

Fires a POST HTTP request to the endpointUrl URL. Callback contains the logged in user.

auth.logout()

Logs out the current logged in user. If logoutEndpointUrl is defined, fires a GET HTTP request to the URL.

auth.hasRole(roleName)

Returns true if logged in user has the desired role, otherwise returns false.

auth.hasAllRoles(roleArray)

Returns true if the logged in user has all the desired roles, otherwise returns false.

auth.hasAnyRole(roleArray)

Returns true if the logged in user has any of the desired roles, otherwise returns false.

auth.hasAdminRole()

Returns true if the logged in user has the adminRole, otherwise returns false.

auth.canAccess(state)

Returns true if logged in user can access the desired state, otherwise returns false.

auth.addCustomProperty(propertyName, propertyValue)

Adds a custom property to this service. Access this property using auth.customProperties['propertyName'] service object or <auth-custom-property property="propertyName"> directive.

This is an example of a valid default RESPONSE returned by a server-side Grails app after firing the login request to endpointUrl and is valid for this module:

{
  "username": "admin",
  "roles": [
    "ROLE_ADMIN",
    "ROLE_USER"
  ],
  "token_type": "Bearer",
  "access_token": "eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINHNJQUFBQUFBQUFBSlZUUVU4VFFSUitXOXVna21BaDBjUURYc1FiMlNaNjdLbmdRa3FHUXJyMmdnbGt1anVzQTdNejY4d3N0QmZUa3h3NFFGUVNFXC84Q1wvMFF2XC9nQ2pCNitjdmZwbW9XdzFKc1E1YmQ3NzV2dSs5NzJkOHd1b0dRM1BFazI1TUg0bThvUkwzMlNheThTd0tOZmNEdjNjTUIweld5QldDMkFQSzNCNXZBcDRCQ284dGpCSDl1Z0JiUWdxazhaR2Y0OUZ0am5ROEZUcDVJcHhWOU9VSFNxOTcxOXpSMHF6UHdSS2F1KzBBbE5iTUV1alNPWFNkcFFNQmhuWExONkNlbGtqS3RwM3Bmc1JkcGkwbkFvekNaMWlrdllGaXdsTTA5eStVcWpLbWJGdzc5SnNicmxvaE13MkNkek9xREhvN3E5SlF1dXN1NzZ6S1hHQzFcL0FHcW9QTXc0UFpQWEZRM1wvSDR5MG9JbkpvcmFSWjZNbFV4MytWT0hQbEg4Kysrbm53YTlTb0FtTW5pelhmSytzTWxHSDNlXC92V29DTnFMTER5WXNGN0Ntb01NM2N5V3pDODBjOHJmUG02K1A3czRlbmtMbFIxaTVmXC8zc2RDNlNtNjRyTktNYW1yVnhJNlE5ckNLMzFVa1g3cVpmTHlGb1JcL3lOQk1NXC95aHBXWHd0VVJManVGV3R4RGh2QzNlN0d5VFlhVDFmYjNlTUs4NVlxQmVsYmhCdTdxeTBTYnRGXC90Rm9yM2FEdGRhNGNhZG85TUtnNnlock5FNjVST2N6UlhCdTR6NVJ1T1wvam42ZGZUaDVcL1J4ZHJVRHVnSW1lNHQzb0o2dVJwbittMzUyZnoweDkrSEJjcGpGXC9FYjZBQ1VmMVZBd0FBIiwic3ViIjoiYWRtaW4iLCJyb2xlcyI6WyJST0xFX0FETUlOIiwiUk9MRV9SRVNQX0ZJTElBTCIsIlJPTEVfUkVTUF9JR1JFSkEiLCJST0xFX1VTRVIiXSwiZXhwIjoxNDY0MTg0NDM3LCJpYXQiOjE0NjQxODA4Mzd9.TFIhXZTcrgcPu5Duj7jnjkIl7S4_SyyCgi6ycT4DY8w",
  "expires_in": 3600,
  "refresh_token": "eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINHNJQUFBQUFBQUFBSlZUUVU4VFFSUitXOXVna21BaDBjUURYc1FiMlNaNjdLbmdRa3FHUXJyMmdnbGt1anVzQTdNejY4d3N0QmZUa3h3NFFGUVNFXC84Q1wvMFF2XC9nQ2pCNitjdmZwbW9XdzFKc1E1YmQ3NzV2dSs5NzJkOHd1b0dRM1BFazI1TUg0bThvUkwzMlNheThTd0tOZmNEdjNjTUIweld5QldDMkFQSzNCNXZBcDRCQ284dGpCSDl1Z0JiUWdxazhaR2Y0OUZ0am5ROEZUcDVJcHhWOU9VSFNxOTcxOXpSMHF6UHdSS2F1KzBBbE5iTUV1alNPWFNkcFFNQmhuWExONkNlbGtqS3RwM3Bmc1JkcGkwbkFvekNaMWlrdllGaXdsTTA5eStVcWpLbWJGdzc5SnNicmxvaE13MkNkek9xREhvN3E5SlF1dXN1NzZ6S1hHQzFcL0FHcW9QTXc0UFpQWEZRM1wvSDR5MG9JbkpvcmFSWjZNbFV4MytWT0hQbEg4Kysrbm53YTlTb0FtTW5pelhmSytzTWxHSDNlXC92V29DTnFMTER5WXNGN0Ntb01NM2N5V3pDODBjOHJmUG02K1A3czRlbmtMbFIxaTVmXC8zc2RDNlNtNjRyTktNYW1yVnhJNlE5ckNLMzFVa1g3cVpmTHlGb1JcL3lOQk1NXC95aHBXWHd0VVJManVGV3R4RGh2QzNlN0d5VFlhVDFmYjNlTUs4NVlxQmVsYmhCdTdxeTBTYnRGXC90Rm9yM2FEdGRhNGNhZG85TUtnNnlock5FNjVST2N6UlhCdTR6NVJ1T1wvam42ZGZUaDVcL1J4ZHJVRHVnSW1lNHQzb0o2dVJwbittMzUyZnoweDkrSEJjcGpGXC9FYjZBQ1VmMVZBd0FBIiwic3ViIjoiYWRtaW4iLCJyb2xlcyI6WyJST0xFX0FETUlOIiwiUk9MRV9SRVNQX0ZJTElBTCIsIlJPTEVfUkVTUF9JR1JFSkEiLCJST0xFX1VTRVIiXSwiaWF0IjoxNDY0MTgwODM3fQ.sIe0FyW7UEH3Yc21KwfDymdKfStBKX9Zf6dsNCuvMn0"
}

Multiple Endpoints

If you are using version 0.0.8 or older, there is the ability to use multiple endpoints. This is useful if you need to log in in different servers.

By default, there is a default endpoint pre-configured for your app. To configure an additional endpoint, use the addEndpoint function of the authConf provider as follows:

angular.module('myModule').config(function(authConfProvider) {
  authConfProvider.addEndpoint('other', {
    endpointUrl: 'http://myServer/myOtherLoginEndpoint',
    usernameFormProperty: 'username',
    passwordFormProperty: 'password',
    tokenProperty: 'token',
    usernameProperty: 'username',
    adminRole: 'administration',
    functionIfAuthenticated: function (authService, data) {
      console.log('user is authenticated in another endpoint');
    }
  });
});

You can use the same configurations that is available for the default endpoint.

To change your application to the endpoint you created, you can either use the setEndpoint of the auth service, or pass the endpoint name to the login function.

angular.module('myModule').controller('LoginController', function (auth, $scope, $state) {
  // Use this
  auth.setEndpoint('other');
  
  // or this
  $scope.login = function () {
    auth.login($scope.username, $scope.password, 'other').then(function () {
      console.log('logged in');
    });
  }
});

You don't need to set the endpoint to default. It's selected by default.

Using directives

This plugin has some directives to make your life easier. They are:

auth-username

Writes the current logged in username.

<div class="myDivClass"><auth-username></auth-username></div>

auth-custom-property

Writes the desired custom property.

<div class="myDivClass"><auth-custom-property property="myProperty"></auth-custom-property></div>
<div class="myDivClass" auth-custom-property="myProperty"></div>

auth-logged-in

Only prints the content if user is logged in.

<auth-logged-in>I will be visible only to logged in users.</auth-logged-in>
<div auth-logged-in>Me too.</div>

auth-not-logged-in

Only prints the content if user is logged in.

<auth-not-logged-in>I will be visible only to not logged in users.</auth-not-logged-in>
<div auth-not-logged-in>Me too.</div>

auth-has-role

Only prints the content if logged in user has the desired role.

<auth-has-role role="ROLE_CUSTOM">I will be visible only to users that has ROLE_CUSTOM role.</auth-has-role>
<div auth-has-role="ROLE_CUSTOM">Me too.</div>

auth-has-any-role

Only prints the content if logged in user has any of the desired roles. The roles list must be comma-separated.

<auth-has-any-role role="ROLE_CUSTOM,ROLE_CUSTOM_2">I will be visible only to users that has ROLE_CUSTOM or ROLE_CUSTOM_2 roles.</auth-has-any-role>
<div auth-has-any-role="ROLE_CUSTOM,ROLE_CUSTOM_2">Me too.</div>

auth-has-all-roles

Only prints the content if logged in user has all of the desired roles. The roles list must be comma-separated.

<auth-has-all-roles role="ROLE_CUSTOM,ROLE_CUSTOM_2">I will be visible only to users that has ROLE_CUSTOM and ROLE_CUSTOM_2 roles.</auth-has-all-roles>
<div auth-has-all-roles="ROLE_CUSTOM,ROLE_CUSTOM_2">Me too.</div>

auth-has-admin-role

Only prints the content if logged in user has the admin role.

<auth-has-admin-role>I will be visible only to users that has administration privileges.</auth-has-admin-role>
<div auth-has-admin-role>Me too.</div>

Contributing

If you want to contribute with this project, feel free to open issues and fork the project.

Package Sidebar

Install

npm i angularjs-auth

Weekly Downloads

2

Version

0.0.12

License

Apache-2.0

Last publish

Collaborators

  • willcrisis