npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@calvear/react-azure-msal-security

v2.1.2

Published

React library (MSAL wrapper) for Azure Active Directory authentication.

Downloads

77

Readme

React Azure MSAL Security

Azure Active Directory security module using MSAL

React library for application security (using MSAL) that eases application protection with Azure session JWT. Exposes multiples hooks for login, logout and secure components.

Structure 📋

├── README.md
├── LICENCE.md
├── CHANGELOG.md
├── .vscode/ # vscode shared development config
├── src/
│   ├── security/
│   │   ├── config/
│   │   │   ├── aad.config.js # MSAL config initialization
│   │   │   └── aad.types.js # AAD and Ms Graph constants
│   │   ├── services/
│   │   │   ├── aad-graph.service.js # basic graph service for user info and avatar
│   │   │   └── aad.service.js # service for handle login, sso and token acquisition
│   │   ├── auth.hook.js # module hooks
│   │   ├── cache.util.js # util for persist graph info
│   │   └── observer.util.js # observer pattern handler
│   └── index.js
├── package.json
├── jsconfig.js
├── .babelrc
├── .eslintrc.json
└── .prettierrc.json

| Files | Description | | ---------------------- | -------------------------------------------------------------------------------------- | | aad.config.js | contains context config | | aad.types.js | contains MSAL anf Microsoft Graph constants | | aad.service.js | main service. Handles MSAL context, session state, login, logout and token acquisition | | aad-graph.service.js | handles Microsoft Graph calls, like user detailed info and profile avatar | | auth.hooks.js | exposed hooks for login, logout and secure components | | index.js | exports router, hooks and routes handler/service |

Features 🎉

✅ Centralized and synchronized session state handling for any authentication event.

✅ Automatic and manual login hooks.

✅ Logout, state and token acquisition hooks.

✅ Refresh token route handler.

✅ User specific profile info and avatar hooks, using Microsoft Graph.

⚠️ Easy to use! but a little hard to customize, i.e. user graph info.

How To Configure 📖

First, you should register a new Azure Active Directory Application in Azure Portal.

In Authentication section add a new platform, selecting Single-Page Application (SPA) and setting up Redirect URIs only, with host (base URL) and token auth URL, for example, for dev:

  • https://localhost:3000/
  • https://localhost:3000/auth

Also, in this section, enable Access tokens and ID tokens in Implicit grant sub-section.

Finally, you should configure permissions in API permissions section, with the minimum permission User.Read, although ideally profile and openid for correct token acquisition.

How To Use 💡

This module, exposes many hooks for handle login, logout and secure React components.

App configuration

In your App.jsx or App.router.jsx you should initialize the authentication service.

import { AuthenticationService } from '@calvear/react-azure-msal-security';

// MSAL config.
const authConfig = {
    clientId: '2a85c521-02fc-4796-8ecc-eaa13eee2e7b', // registered app id from azure
    tenantId: 'ba3947ca-abb7-402e-b1d1-c9284608f497', // maybe common, organizations or consumers also
    loginActionRedirect: '/',
    logoutActionRedirect: null,
    tokenRefreshUri: '/auth', // should exists a blank route in your app
    tokenRenewalOffset: 120,
    navigateToRequestAfterLogin: true,
};

// initializes Microsoft Active Directory authentication service.
AuthenticationService.init(authConfig);

// main react component
export default () => {
    return (
        <div>
            <h1>Welcome to My App</h1>
        </div>
    );
};

| Parameters | Description | | -------------------------------------- | --------------------------------------------------------------- | | [config] | settings | | [config.tenantId] | organization Azure client id | | [config.clientId] | application Azure client id | | [config.loginActionRedirect] | (default: '/') - redirect path after login | | [config.logoutActionRedirect] | (default: null) - redirect path after logout | | [config.tokenRefreshUri] | (default: '/auth') - path for renew auth token | | [config.tokenRenewalOffset] | (default: 120) token renewal interval | | [config.navigateToRequestAfterLogin] | (default: true) - if app redirects to previous path after login | | [config.infoCacheDurationInDays] | (default: 1) - days for store user info cached | | [config.photoCacheDurationInDays] | (default: 3) - days for store user photo cached | | [disabled] | (default: false) - if authentication is disabled globally |

For tenantId also see MSAL Client Config

Token acquisition and blank page/route

For a correct authentication and token renewal operation you should define a blank page or route in your application. This route will be used as iframe for retrieve or renew the token on authentication.

For example, if you're using react-spa-routerizer

// routes.js

export default [
    ...,
    // blank html page for load authentication iframe to refresh the token,
    // also, you should set tokenRefreshUri as '/auth' route.
    {
        key: 'auth-page',
        title: 'Authenticating',
        path: '/auth',
        Child: () => null
    },
    ...
];

☑️ Check Authentication State

import { useAuthenticationState } from '@calvear/react-azure-msal-security';

// react component
export default () => {
    const { authenticated, authenticating, error } = useAuthenticationState();

    return (
        <div>
            <h1>User is authenticated?: {authenticated ? 'yeah' : 'no'}</h1>
        </div>
    );
};

| Returning Modules | Description | | ---------------------- | -------------------------------- | | state | object with authentication state | | state.authenticated | if user is authenticated | | state.authenticating | if service is authenticating | | state.error | error object |

☑️ Automatic Login

import { useAuthentication } from '@calvear/react-azure-msal-security';

// react component
export default () => {
    const { authenticated, authenticating, error } = useAuthentication();

    if (authenticating) return <div>Authenticating...</div>;

    if (!authenticated) return <div>403: Not Authorized - {error.message}</div>;

    return (
        <div>
            <h1>Welcome to My App</h1>
        </div>
    );
};

| Returning Modules | Description | | ---------------------- | -------------------------------- | | state | object with authentication state | | state.authenticated | if user is authenticated | | state.authenticating | if service is authenticating | | state.error | error object |

| Parameters | Description | | -------------------- | ------------------------------------------------------ | | [config] | settings | | [config.loginType] | (default: loginRedirect) - loginRedirect or loginPopup |

☑️ Manual Login

import { Redirect } from 'react-router-dom';
import { useAuthenticationState, useLogin } from '@calvear/react-azure-msal-security';

// react component
export default () => {
    const login = useLogin();
    const { authenticated, authenticating, error } = useAuthenticationState();

    if(authenticating)
        return <div>Authenticating...</div>;

    if(!authenticated)
        return <div>403: Not Authorized - {error.message}</div>;

    if(authenticated)
        return <Redirect to='/home'>;

    return (
        <div>
            <button onClick={login}>Log In</button>
        </div>
    );
}

| Returning Modules | Description | | ----------------- | ------------------------------------------------- | | login | (login) function for trigger login/authentication |

| Parameters | Description | | ------------- | ---------------------------------------------------- | | [loginType] | (default: loginRedirect) loginRedirect or loginPopup |

☑️ Logout

import { useLogout } from '@calvear/react-azure-msal-security';

// react component
export default () => {
    const logout = useLogout();

    return (
        <div>
            <button onClick={logout}>Log Out</button>
        </div>
    );
};

| Returning Modules | Description | | ----------------- | ------------------- | | logout | function for logout |

☑️ Acquire Token

You can acquire a JWT access token for API securing.

import { useState, useEffect } from 'react';
import { useAcquireToken } from '@calvear/react-azure-msal-security';

// react component
export default () => {
    const [token, setToken] = useState();
    const { authenticated } = useAuthentication();
    // use it only if authentication was succeeded
    const acquireToken = useAcquireToken();

    useEffect(() => {
        if (authenticated) {
            acquireToken().then((tkn) => setToken(tkn));
        }
    }, [authenticated]);

    return (
        <div>
            <h1>Welcome to My App</h1>
        </div>
    );
};

| Returning Modules | Description | | ----------------- | ------------------------------------------ | | acquireToken | async function for acquire an access token |

| Parameters | Description | | --------------------- | --------------------------------------------------------------- | | [forceTokenRefresh] | (default: false) - forces to renew token from active directory. |

☑️ Graph Info

You can retrieves user account detailed info and profile avatar from Microsoft Graph api with hooks.

import { useAccountInfo } from '@calvear/react-azure-msal-security';

// react component
export default () => {
    const { loading, info, error } = useAccountInfo();

    if (loading) return <div>Loading User Info...</div>;

    if (error) return <div>User info cannot be loaded: {error.message}</div>;

    return (
        <div>
            <h1>User Info</h1>
            <h3>Name: {info.displayName}</h3>
        </div>
    );
};

| Returning Modules | Description | | ----------------- | ---------------------- | | state | object with info state | | state.loading | if info is loading | | state.info | account info | | state.error | error object |

import { useAccountAvatar } from '@calvear/react-azure-msal-security';

// react component
export default () => {
    const { loading, avatar, error } = useAccountAvatar();

    if (loading) return <div>Loading User Avatar...</div>;

    if (error) return <div>User avatar cannot be loaded: {error.message}</div>;

    return (
        <div>
            <img alt="user-avatar" src={avatar} />
        </div>
    );
};

| Returning Modules | Description | | ----------------- | ------------------------ | | state | object with avatar state | | state.loading | if avatar is loading | | state.avatar | account avatar in base64 | | state.error | error object |

| Parameters | Description | | ------------ | ------------------------------------------------------------------------------------------------------------------------- | | [size] | (default: 648x648) avatar sizes. Values maybe 48x48, 64x64, 96x96, 120x120, 240x240, 360x360, 432x432, 504x504 or 648x648 |

Linting 🧿

Project uses ESLint, for code formatting and code styling normalizing.

  • eslint: JavaScript and React linter with Airbnb React base config and some other additions.
  • prettier: optional Prettier config.

For correct interpretation of linters, is recommended to use Visual Studio Code as IDE and install the plugins in .vscode folder at 'extensions.json', as well as use the config provided in 'settings.json'

Changelog 📄

For last changes see CHANGELOG.md file for details.

Built with 🛠️

  • React - the most fabulous JavaScript framework.
  • MSAL - Microsoft Authentication Library for JavaScript.
  • axios - Promise based HTTP client.

License 📄

This project is licensed under the MIT License - see LICENSE.md file for details.


⌨ by Alvear Candia, Cristopher Alejandro