Azure AD Login for your SPA using React Hooks

In this tutorial we are implementing Microsoft Azure Ad Login in React single-page app and retrieve user information using @azure/msal-browser.

The MSAL library for JavaScript enables client-side JavaScript applications to authenticate users using Azure AD work and school accounts (AAD), Microsoft personal accounts (MSA) and social identity providers like Facebook, Google, LinkedIn, Microsoft accounts, etc. through Azure AD B2C service. It also enables your app to get tokens to access Microsoft Cloud services such as Microsoft Graph.

Azure application registration

You can register you web app using  Microsoft tutorial.

In the below App.js file code we are using Context and Reducer for managing the login state. useReducer allows functional components in React access to reducer functions from your state management

First we initialize the initial values for reducer,
Reducers are functions that take the current state and an action as arguments, and return a new state result. In other words, (state, action) => newState

You can see the code form 17 line where we created reducer with using switch case “LOGIN” and “LOGOUT”. and from Line 58 we use the context that defined in line 6 and passing the reducer values to it.

And In a line 66 : we are checking the state.isAuthenticated or not , if it’s not the page redirect to the home page and if it’s Authenticated it will be redirected to the admin dashboard home page.

App.Js

import React, { useReducer } from "react";
import { createBrowserHistory } from "history";
import { Router, Route, Switch, Redirect } from "react-router-dom";
import AdminLayout from "layouts/Admin.js";
import HomeLayout from "layouts/Home.js";
export const AuthContext = React.createContext();
const hist = createBrowserHistory();


const initialState = {
    isAuthenticated: false,
    user: null,
    token: null,
    
};

export const reducer = (state, action) => {
    switch (action.type) {
        case "LOGIN":
            localStorage.setItem("user", action.payload.user);
            localStorage.setItem("token", action.payload.token);
            return {
                ...state,
                isAuthenticated: true,
                user: action.payload.user,
                token: action.payload.token
            };
        case "LOGOUT":
            localStorage.clear();
            return {
                ...state,
                isAuthenticated: false,
                user: null
            };
        default:
            return state;
    }
};

function App() {
    const [state, dispatch] = useReducer(reducer, initialState);

    React.useEffect(() => {
        const user = localStorage.getItem('user') || null;
        const token = localStorage.getItem('token') || null;

        if (user && token) {
            dispatch({
                type: 'LOGIN',
                payload: {
                    user,
                    token
                }
            })
        }
    }, [])
    return (
        <AuthContext.Provider
            value={{
                state,
                dispatch
            }}
        >
            <Router history={hist}>
                <Switch>
                    <div className="App">{!state.isAuthenticated ?
                        <>
                            <Route path="/home" render={(props) => <HomeLayout {...props} />} />
                            <Redirect to="/home" /> </> :
                        <><Route path="/admin" render={(props) => <AdminLayout {...props} />} />
                            <Redirect to="/admin/dashboard" /></>}</div>
                </Switch>
            </Router>
        </AuthContext.Provider>
    );
}

export default App;

Now we are coming the the Login Component with Azure Ad using with @azure/msal-browser

In a below code we are importing AuthContext from App.js and PublicClientApplication from @azure/msal-browser.

and In a 7th line we created constant variable “dispatch” with providing the reference of AuthContext then we created the msalInstandce variable using the PublicClientApplication and providing the clientId, authority and redirectUri in auth block.

In a line 22 we created the startlogin function then we created the loginRequest variable and providing the scope for login.

and In a line 31 we use the msalInstance.loginPopup(loginRequest) for getting pop up window for login and in a “loginRespone” variable save the login response. then we are fetching the username and token form loginRespone. dispatch to the AuthContext (see line 41).

And In a line 56 we created a button it’s call the startLogin function on click event.

Login.cs

import React from "react";

import { AuthContext } from "App";
import {  PublicClientApplication } from '@azure/msal-browser';

export const Login = () => {
  const { dispatch } = React.useContext(AuthContext);

  const msalInstance = new PublicClientApplication({

    auth: {
      clientId: "65395645-90dd-4436-84a4-47d7c0e961fc",
      authority: "https://login.microsoftonline.com/common",
      redirectUri: "https://localhost:3000",
    },
    cache: {
      cacheLocation: "sessionStorage",
      storeAuthStateInCookie: true,
           }
  });

  const startLogin = async (e) => {
    e.preventDefault();
   
    var loginRequest = {
      scopes: ["65395645-90dd-4436-84a4-47d7c0e961fc/.default"] // optional Array<string>
    };
   
    try {
      
      const loginResponse = msalInstance.loginPopup(loginRequest);
      
      const username = (await loginResponse).account.username;
      const token = (await loginResponse).accessToken;

      const resJson = {
        token: token,
        user: username
      };

      dispatch({
        type: "LOGIN",
        payload: resJson
      })
      console.log("Login successfully");
    } catch (err) {

      console.log("Authentication Failed.....");
      console.log(err);
    }
  }
 
  return (
    <div>

      <button className="btn btn-sm btn-outline-success my-2 my-sm-0" data-toggle="button" onClick={(e) => { startLogin(e) }}>Login</button>

    </div>

  );
};

export default Login;

Above you see we used the reducer and context in App.js file and crated a Login Component.

Conclusion

Now we can import the Login component anywhere in a project where we want to login button that uses the Azure AD for Authentication.

Getting Non-religious with React Library – Part I (The Concepts)

The Javascript wars are raging! Are you with the purist Javascript nerds or on traditional jQuery’s side or would you prefer lean React or does Google’s AngularJS get your mojo? This post isn’t about this religious debate.

This three part series is going to introduce the React to developers. React was created by Facebook and is supported by them.

We start slow in this post but will end with a working example of React application. We are interested in building an enterprise application and would end up adding a Grid to the page in Part III of this post.

The one thing I love about React is that it is non-religious. It is ready to embrace any JavaScript technology that you can throw at React. React is a very light weight framework and only contains the capability of rendering the view. React makes no assumptions about the rest of the technology stack used and can plug in with any Model or Model View framework.

Surprisingly with all that versatility, React is very simple to learn and can be introduced incrementally into an existing project (part running React and part running jQuery).

Here are some concepts to be aware about:

  1. Virtual DOM: Virtual DOM is a shadow of the page DOM but is never updated. It is only destroyed and re-rendered for the specific components that have changed. This makes updates blazingly fast.
  2. One Way Databinding: Closely tied to the above, only inputs are accepted as change of state. Change in the property doesn’t trigger the update on the DOM automatically.
  3. JSX: This is a JavaScript extension that allows XML to be embedded within React components directly. Think of this as a light weight template library.
  4. Classes/ Components: The heart of React. Everything rendered by React is a component. Components are composable and can be composed of additional components.
    1. Properties/ Props: React Components have properties that are used to accept input from other components and used to render the components directly.
    2. Events: Allows components to respond to various input activities.
    3. State: Components can maintain state that is only available to the specific component i.e. sort of a private data.
  5. References: One way binding constructs that allow inputs to be accessed from the backend.
  6. Developer Tools: React Developer Tools are available for Chrome and Firefox as a browser extension for React. It allows you to inspect the React component hierarchies in the virtual DOM.

React CLI

The easiest way to get started with React is through create-react-app CLI (the official React CLI). So, fire up your command line interface and get cracking..

First install the create-react-app:

npm install –g create-react-app

Then we can create a new app, and that bootstraps the entire application. We simply use “create-react-app my-app” and render it with npm start. Remember to browse to the root directory where you want to create your node application. I tend to keep my node projects in the “Documents\nodeprojects” directory.

create-react-app my-app

cd my-app

npm start

These commands just runs through a npm script to set up a server for us and kick off the app. You should see a screen as follows:

Note: It does take a while to install everything. Have patience as npm creates the first React app for you.

This was probably the fastest way to get started with node. In the next part, we will cover building a React application from scratch.

Kendo UI

Resources from Webinar “Coexist: AngularJS 2.0 and React with Kendo UI”

On Jun 23 2016 we conducted yet another webinar. This time we talked about Kendo UI Components for Angular JS 2.0 and React JS. This blog post is a recap of the webinar. You will find the slide deck and video recording in this blog post. If you missed attending live or had to leave in between dont worry – we have you covered. Just go through this blog post to catch up on what you missed. Continue reading