6.1.7 • Published 5 years ago

visla-auth v6.1.7

Weekly downloads
2
License
MIT
Repository
github
Last release
5 years ago

VislaAuth - Angular6+ Auth Module

This module is created to handle all authentication requirements in the Angular6.

Features:

  • interceptor to add token to header request...
  • interceptor to handle 401 error response. Interceptor automatically refresh token, and repeat all failed requests...
  • directive to easy hide/show specific HTML based on user's role...
  • authentication guard to allow only logged in users to access...
  • guard to allow only users with specific role to access...
  • service for: login, logout, change password, registration...

Requirements:

  • Angular 6+
  • RouterModule with at least one path
  • for login endpoint: response object should have specific property names: "access_token" and "token_type" (and "refresh_token" if you want to use this token for refreshing expired token)
  • for handling the roles in HTML and route guard, getMe endpoint response should have object with a "role" property
  • your typescript version should be at least 2.9.2
"typescript": "~2.9.2" // package.json

Installation:

npm install --save visla-auth
import { AuthVislaModule } from 'visla-auth';
import { IConfig } from 'visla-auth';

export const config: IConfig = {
  baseUrl: 'https://www.example.com',
  apiEndpoints: {
    register: 'auth/register', 
    login: 'auth/login', 
    logout: 'auth/logout', 
    changePassword: 'user/change_password', 
    recoveryPassword: 'auth/recovery_password', 
    resetPassword: 'auth/reset_password', 
    refreshToken: 'auth/refresh_token',
    getMe: 'auth/user'
  },
  appRoutes: {
    loginPage: 'login-page',
    baseRootForAuthUsers: '',
    redirectUrlWithNoPermission: 'login-page'
  }
};

@NgModule({
  declarations: [
    ...
  ],
  imports: [
    RouterModule.forRoot( // router is required
      [
        { path: 'welcome-page', component: WelcomepageComponent}
      ]
    ),
    BrowserModule,
    AuthVislaModule.forRoot(config)
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Configuration object:

Configuration object have this interface:

export interface IConfig {
    baseUrl: string;
    apiEndpoints: {
        register?: string; // used for: this.auth.register(data).subscribe((response) => {});
        changePassword?: string;  // used for: this.auth.changePassword(data).subscribe((response) => {});
        recoveryPassword?: string; // used for: this.auth.recoveryPassword(data).subscribe((response) => {});
        resetPassword?: string; // used for: this.auth.resetPassword(data).subscribe((response) => {});
        login?: string;  // used for: this.auth.login(data).subscribe((response) => {});
        logout?: string;  // used for: this.auth.logout();
        refreshToken?:  string; // handled by interceptor
        getMe?: string; // used for: this.auth.getMe().subscribe(...);
      };
      appRoutes: {
        loginPage?: string; // redirect to this path if user is not authenticated
        baseRootForAuthUsers?: string; // redirect to this path loggedin users when user try to access some other page
        redirectUrlWithNoPermission?: string; // redirect to this path when user try to access to page with no permission
      };
}

Usage:

    <!-- only authenticated users will see this -->
    <div *permission="'auth'">Welcome, you are logged in.</div>
    <!-- only unauthenticated users will see this -->
    <div *permission="'unauth'">Please, login.</div>
    <!-- only user with role admin will see this -->
    <div *permission="['admin']">You are the boss.</div>
    <!-- only user with role 'user' will see this -->
    <div *permission="['user']">See the products.</div>
    <!-- user and author will see this -->
    <div *permission="['user', 'author']">See this, click here.</div>

Login response from API:

    import { AuthService } from 'visla-auth';
    ...

    this.auth.login(credentials).subscribe((response) => {})
    {
        access_token: 123, // required
        refresh_token: 234, // it's NOT required. If your backend returns "refresh_token" property, "refresh_token" will be user for refreshing. Otherwise, "access_token" will be used also used for refreshing.
        token_type: 'Bearer', // required
        anything_else: 'it is no required'
    }

Get user object (me object) response from API:

This part is required only if you want to use *permission directive (to show/hide some HTML based on user role) or Role guard (to allow navigate to specific page based on user role).

    import { AuthService } from 'visla-auth';
    ...
    // after login:
    this.auth.getMe().subscribe((response) => {})
    {
        role: 'admin', // required
        anything_else: 'it is no required'
    }

Login example:

    import { Component } from '@angular/core';
    import { AuthService } from 'visla-auth';

    @Component({
        selector: 'app-root',
        templateUrl: './app.component.html',
        styleUrls: ['./app.component.css']
    })
    export class AppComponent {
    constructor(private auth: AuthService) {
        const credentials = { // object you pass to the API
            email: "myemail@example.com",
            password: "mypassword"
        };
        this.auth.login(credentials).subscribe((response) => {
                console.log('You are logged in, you have a token in localStorage, and interceptors will handle it.');
                // if your app has a roles, get it from api:
                this.auth.getMe().subscribe((response) => {
                    console.log('You have user/me object. Now, Module know user role.')
                }, (error) => {
                    alert('Error, try again');
                });
            }
            }, (error) => {
                alert('Login error, try again');
            });
        }
    }

Routing guards:

To working with guards, first we need to know user role (see example before):

    import { AuthService } from 'visla-auth';
    ...

    this.auth.getMe().subscribe((response) => {
            console.log('You have user/me object. Now, Module know user role.')
        }, (error) => {
            alert('Error, try again');
        });
    }

Prevent some routes from unauthorized users. "acceptedRoles" property is required. only admin can visit this pages

    import { RoleGuard } from 'visla-auth';
    ....

    {
        path: 'admin-page',
        component: AdminComponent,
        data: {
            acceptedRoles: ['admin'] // in array of string we define roles that can access to this path
        },
        canActivate: [RoleGuard] // only admin can visit this pages
    }
    import { RoleGuard } from 'visla-auth';
    ....

    {
        path: 'admin-page',
        component: AdminComponent,
        data: {
            acceptedRoles: ['admin', 'author'] // in array of string we define roles that can access to this path
        },
        canActivate: [RoleGuard] // only admin, and author can visit this pages
    }
    import { AuthenticatedRequiredGuard } from 'visla-auth';
    ....

    {
        {
        path: 'welcome-page',
        component: WelcomeComponent,
        canActivate: [AuthenticatedRequiredGuard] // any authenticated user can visit this page
    }
    import { NotAuthenticatedOnlyGuard } from 'visla-auth';
    ....

    {
        {
        path: 'login-page',
        component: LoginComponent,
        canActivate: [NotAuthenticatedOnlyGuard] // any NOT authenticated user can visit this page. Auth users can NOT visit this page
    }

Auth Service:

List of functions you can use (if you pass endpoints in the config object):

    import { AuthService } from 'visla-auth';

    @Component({
        selector: 'app-root',
        templateUrl: './app.component.html',
        styleUrls: ['./app.component.css']
    })
    export class AppComponent {
    constructor(private auth: AuthService) {

        // METHODS:
        this.auth.register(data).subscribe((response) => {})

        this.auth.login(data).subscribe((response) => {})

        this.auth.getMe().subscribe((response) => {})

        this.auth.changePassword(data).subscribe((response) => {})

        this.auth.recoveryPassword(data).subscribe((response) => {})

        this.auth.resetPassword(data).subscribe((response) => {})

        this.auth.logout();

        // PROPERTY
        console.log(this.auth.isLoggedIn); // boolean

        // SUBJECT
        // subscribe to the userIsAuth$ subject, and listen the login changes
        this.auth.userIsAuth$.subscribe((isAuth: boolean) => {
            console.log(`User updated auth to: ${isAuth}`);
        });

    }

Logout

    import { AuthService } from 'visla-auth';
    ...

    this.auth.logout(); // logout 
    this.auth.logout(true); // logout and navigate to the login page (if you pass loginPage property in config object)

User service

    import { UserService } from 'visla-auth';
    ...

    // PROPERTIES:
    console.log(this.user.me); // user/me object
    console.log(this.user.role); // 'admin'

    // SUBJECT
    // subscribe to the userRole$ subject, and listen the role changes
    this.user.userRole$.subscribe((role: string) => {
      console.log(`Role is updated to: ${role}`);
    });
6.1.7

5 years ago

6.1.6

5 years ago

6.1.5

5 years ago

6.1.4

6 years ago

6.1.3

6 years ago

6.1.2

6 years ago

6.1.1

6 years ago

6.1.0

6 years ago

6.0.6

6 years ago

6.0.5

6 years ago

6.0.4

6 years ago

6.0.3

6 years ago

6.0.2

6 years ago

6.0.1

6 years ago

6.0.0

6 years ago

0.0.2

6 years ago

0.0.1

6 years ago