There is a great example here which inspired me.
I have removed the calendar section and migrated the React part to Hooks.
Step 1, Azure application registration
This part could be exactly like Microsoft tutorial
Step 2
Create a react application using
npx create-react-app azure-ad-react
cd ./azure-ad-react
using npm or yarn add the following dependencies:
"@microsoft/microsoft-graph-client": "^2.0.0",
"msal": "^1.2.1",
Add the config.json to your src folder.
module.exports = {
appId: '{Your azure application (client) id}',
redirectUri: 'http://localhost:3000/',
scopes: [
"user.read"
]
};
note: You can get the Application (client) ID from Azure portal from the Overview tab of your App-registrations panel.
src\GraphService.js
var graph = require('@microsoft/microsoft-graph-client');
function getAuthenticatedClient(accessToken) {
// Initialize Graph client
const client = graph.Client.init({
// Use the provided access token to authenticate
// requests
authProvider: (done) => {
done(null, accessToken.accessToken);
}
});
return client;
}
export async function getUserDetails(accessToken) {
const client = getAuthenticatedClient(accessToken);
const user = await client.api('/me').get();
return user;
}
src\App.js
import React, { useEffect, useState } from "react";
import "./App.css";
import { UserAgentApplication } from "msal";
import { getUserDetails } from "./GraphService";
import config from "./Config";
function App() {
const userAgentApplication = new UserAgentApplication({
auth: {
clientId: config.appId,
redirectUri: config.redirectUri
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: true
}
});
const [loginState, setLoginState] = useState({
isAuthenticated: false,
user: {},
error: null
});
useEffect(() => {
let user = userAgentApplication.getAccount();
console.log(user);
if (user) {
// Enhance user object with data from Graph
getUserProfile();
}
}, []);
const login = async () => {
try {
await userAgentApplication.loginPopup({
scopes: config.scopes,
prompt: "select_account"
});
await getUserProfile();
} catch (err) {
var error = {};
if (typeof err === "string") {
var errParts = err.split("|");
error =
errParts.length > 1
? { message: errParts[1], debug: errParts[0] }
: { message: err };
} else {
error = {
message: err.message,
debug: JSON.stringify(err)
};
}
setLoginState({
isAuthenticated: false,
user: {},
error: error
});
}
};
const logout = () => {
userAgentApplication.logout();
};
const getUserProfile = async () => {
try {
// Get the access token silently
// If the cache contains a non-expired token, this function
// will just return the cached token. Otherwise, it will
// make a request to the Azure OAuth endpoint to get a token
var accessToken = await userAgentApplication.acquireTokenSilent({
scopes: config.scopes
});
if (accessToken) {
// Get the user's profile from Graph
var user = await getUserDetails(accessToken);
setLoginState({
isAuthenticated: true,
user: {
displayName: user.displayName,
email: user.mail || user.userPrincipalName,
givenName: user.givenName,
surname: user.surname
},
error: null
});
}
} catch (err) {
var error = {};
if (typeof err === "string") {
var errParts = err.split("|");
error =
errParts.length > 1
? { message: errParts[1], debug: errParts[0] }
: { message: err };
} else {
error = {
message: err.message,
debug: JSON.stringify(err)
};
}
setLoginState({
isAuthenticated: false,
user: {},
error: error
});
}
};
return (
<div>
<p>Display name: {loginState.user.displayName}</p>
<p>Username: {loginState.user.userName}</p>
<p>First name: {loginState.user.givenName}</p>
<p>Last name: {loginState.user.surname}</p>
{loginState.error ? <p>loginState.error</p> : null}
{loginState.isAuthenticated ? (
<div>
<h4>Welcome {loginState.user.displayName}!</h4>
<button color="primary" onClick={logout}>
Logout
</button>
</div>
) : (
<button color="primary" onClick={login}>
Click here to sign in
</button>
)}
</div>
);
}
export default App;
Step 3: Running the application.
npm start
Be aware you would get a warning while running this application:
Compiled with warnings.
./src/App.js
Line 35:6: React Hook useEffect has missing dependencies: 'getUserProfile' and 'userAgentApplication'. Either include them or remove the dependency array react-hooks/exhaustive-deps
Search for the keywords to learn more about each warning.
To ignore, add // eslint-disable-next-line to the line before.
The reason for this warning is the code is using getUserProfile and userAgentApplication inside the useEffect. You can read more about it here or you can add the eslint to ignore it.
Top comments (0)