Reading a Token From Url in React
This browser is no longer supported.
Upgrade to Microsoft Edge to take reward of the latest features, security updates, and technical support.
Tutorial: Sign in users and phone call the Microsoft Graph API from a React unmarried-page app (SPA) using auth code flow
In this tutorial, you build a React single-page awarding (SPA) that signs in users and calls Microsoft Graph by using the authorization code flow with PKCE. The SPA y'all build uses the Microsoft Authentication Library (MSAL) for React.
In this tutorial:
- Create a React project with
npm
- Register the application in the Azure portal
- Add together code to support user sign-in and sign-out
- Add together code to call Microsoft Graph API
- Exam the app
MSAL React supports the authorization code menses in the browser instead of the implicit grant menses. MSAL React does Non support the implicit flow.
Prerequisites
- Node.js for running a local webserver
- Visual Studio Code or some other code editor
How the tutorial app works
The application you create in this tutorial enables a React SPA to query the Microsoft Graph API by acquiring security tokens from the the Microsoft identity platform. Information technology uses the Microsoft Authentication Library (MSAL) for React, a wrapper of the MSAL.js v2 library. MSAL React enables React xvi+ applications to authenticate enterprise users by using Azure Active Directory (Azure AD), and also users with Microsoft accounts and social identities like Facebook, Google, and LinkedIn. The library as well enables applications to get access to Microsoft deject services and Microsoft Graph.
In this scenario, after a user signs in, an access token is requested and added to HTTP requests in the dominance header. Token acquisition and renewal are handled by the Microsoft Authentication Library for React (MSAL React).
Libraries
This tutorial uses the following libraries:
Library | Description |
---|---|
MSAL React | Microsoft Hallmark Library for JavaScript React Wrapper |
MSAL Browser | Microsoft Authentication Library for JavaScript v2 browser packet |
Go the completed code sample
Adopt to download this tutorial's completed sample project instead? To run the project by using a local web server, such as Node.js, clone the ms-identity-javascript-react-spa repository:
git clone https://github.com/Azure-Samples/ms-identity-javascript-react-spa
Then, to configure the lawmaking sample earlier you lot execute information technology, skip to the configuration step.
To go on with the tutorial and build the awarding yourself, move on to the side by side department, Prerequisites.
Create your project
Once you lot have Node.js installed, open a concluding window so run the following commands:
npx create-react-app msal-react-tutorial # Create a new React app cd msal-react-tutorial # Alter to the app directory npm install @azure/msal-browser @azure/msal-react # Install the MSAL packages npm install react-bootstrap bootstrap # Install Bootstrap for styling
Yous have now bootstrapped a pocket-sized React project using Create React App. This will be the starting indicate the residue of this tutorial will build on. If you would like to see the changes to your app as yous are working through this tutorial you can run the following command:
npm starting time
A browser window should be opened to your app automatically. If information technology does not, open up your browser and navigate to http://localhost:3000. Each time you lot save a file with updated code the folio will reload to reflect the changes.
Register your application
Follow the steps in Single-folio application: App registration to create an app registration for your SPA by using the Azure portal.
In the Redirect URI: MSAL.js two.0 with auth code menstruum step, enter http://localhost:3000
, the default location where create-react-app will serve your application.
Configure your JavaScript SPA
-
Create a file named authConfig.js in the src folder to comprise your configuration parameters for authentication, so add the following code:
export const msalConfig = { auth: { clientId: "Enter_the_Application_Id_Here", authorization: "Enter_the_Cloud_Instance_Id_Here/Enter_the_Tenant_Info_Here", // This is a URL (e.thousand. https://login.microsoftonline.com/{your tenant ID}) redirectUri: "Enter_the_Redirect_Uri_Here", }, cache: { cacheLocation: "sessionStorage", // This configures where your cache will be stored storeAuthStateInCookie: imitation, // Set up this to "true" if you are having issues on IE11 or Edge } }; // Add together scopes here for ID token to be used at Microsoft identity platform endpoints. export const loginRequest = { scopes: ["User.Read"] }; // Add together the endpoints here for Microsoft Graph API services yous'd like to use. export const graphConfig = { graphMeEndpoint: "Enter_the_Graph_Endpoint_Here/v1.0/me" };
-
Change the values in the
msalConfig
section as described here:Value name About Enter_the_Application_Id_Here
The Application (client) ID of the application y'all registered. Enter_the_Cloud_Instance_Id_Here
The Azure deject instance in which your application is registered. For the main (or global) Azure deject, enter https://login.microsoftonline.com
. For national clouds (for case, Communist china), you can find appropriate values in National clouds.Enter_the_Tenant_Info_Here
Set up to ane of the following options: If your application supports accounts in this organizational directory, supersede this value with the directory (tenant) ID or tenant name (for example, contoso.microsoft.com). If your application supports accounts in any organizational directory, supercede this value with organizations. If your application supports accounts in any organizational directory and personal Microsoft accounts, supercede this value with common. To restrict back up to personal Microsoft accounts only, supersede this value with consumers. Enter_the_Redirect_Uri_Here
Replace with http://localhost:3000. Enter_the_Graph_Endpoint_Here
The instance of the Microsoft Graph API the awarding should communicate with. For the global Microsoft Graph API endpoint, replace both instances of this string with https://graph.microsoft.com
. For endpoints in national cloud deployments, see National cloud deployments in the Microsoft Graph documentation.For more information about available configurable options, see Initialize client applications.
-
Open up upwards the src/index.js file and add the following imports:
import "bootstrap/dist/css/bootstrap.min.css"; import { PublicClientApplication } from "@azure/msal-browser"; import { MsalProvider } from "@azure/msal-react"; import { msalConfig } from "./authConfig";
-
Underneath the imports in src/index.js create a
PublicClientApplication
example using the configuration from step 1.const msalInstance = new PublicClientApplication(msalConfig);
-
Find the
<App />
component in src/index.js and wrap information technology in theMsalProvider
component. Your render function should look like this:ReactDOM.render( <React.StrictMode> <MsalProvider instance={msalInstance}> <App /> </MsalProvider> </React.StrictMode>, document.getElementById("root") );
Sign in users
Create a folder in src chosen components and create a file inside this folder named SignInButton.jsx. Add the lawmaking from either of the following sections to invoke login using a pop-upwards window or a total-frame redirect:
Sign in using pop-ups
Add the following code to src/components/SignInButton.jsx to create a button component that will invoke a pop-up login when selected:
import React from "react"; import { useMsal } from "@azure/msal-react"; import { loginRequest } from "../authConfig"; import Button from "react-bootstrap/Button"; office handleLogin(example) { case.loginPopup(loginRequest).catch(due east => { console.error(eastward); }); } /** * Renders a push which, when selected, will open a popup for login */ export const SignInButton = () => { const { instance } = useMsal(); return ( <Button variant="secondary" className="ml-auto" onClick={() => handleLogin(instance)}>Sign in using Popup</Push> ); }
Sign in using redirects
Add the following code to src/components/SignInButton.jsx to create a button component that will invoke a redirect login when selected:
import React from "react"; import { useMsal } from "@azure/msal-react"; import { loginRequest } from "../authConfig"; import Button from "react-bootstrap/Push button"; role handleLogin(instance) { instance.loginRedirect(loginRequest).grab(e => { panel.error(e); }); } /** * Renders a push which, when selected, will redirect the page to the login prompt */ export const SignInButton = () => { const { instance } = useMsal(); return ( <Button variant="secondary" className="ml-auto" onClick={() => handleLogin(instance)}>Sign in using Redirect</Button> ); }
Add the sign-in button
-
Create another file in the components folder named PageLayout.jsx and add the following code to create a navbar component that will comprise the sign-in button y'all just created:
import React from "react"; import Navbar from "react-bootstrap/Navbar"; import { useIsAuthenticated } from "@azure/msal-react"; import { SignInButton } from "./SignInButton"; /** * Renders the navbar component with a sign-in push button if a user is not authenticated */ export const PageLayout = (props) => { const isAuthenticated = useIsAuthenticated(); return ( <> <Navbar bg="master" variant="nighttime"> <a className="navbar-brand" href="/">MSAL React Tutorial</a> { isAuthenticated ? <bridge>Signed In</span> : <SignInButton /> } </Navbar> <h5><center>Welcome to the Microsoft Authentication Library For React Tutorial</center></h5> <br /> <br /> {props.children} </> ); };
-
Now open src/App.js and add supercede the existing content with the following code:
import React from "react"; import { PageLayout } from "./components/PageLayout"; function App() { return ( <PageLayout> <p>This is the main app content!</p> </PageLayout> ); } export default App;
Your app now has a sign-in push which is simply displayed for unauthenticated users!
When a user selects the Sign in using Popup or Sign in using Redirect push for the starting time time, the onClick
handler calls loginPopup
(or loginRedirect
) to sign in the user. The loginPopup
method opens a popular-up window with the Microsoft identity platform endpoint to prompt and validate the user'south credentials. Subsequently a successful sign-in, msal.js initiates the authorization lawmaking catamenia.
At this point, a PKCE-protected authorization lawmaking is sent to the CORS-protected token endpoint and is exchanged for tokens. An ID token, admission token, and refresh token are received by your application and processed by msal.js, and the information independent in the tokens is cached.
Sign users out
In src/components create a file named SignOutButton.jsx. Add together the code from either of the following sections to invoke logout using a pop-up window or a full-frame redirect:
Sign out using pop-ups
Add the following lawmaking to src/components/SignOutButton.jsx to create a button component that will invoke a pop-upwards logout when selected:
import React from "react"; import { useMsal } from "@azure/msal-react"; import Button from "react-bootstrap/Button"; function handleLogout(example) { example.logoutPopup().catch(e => { console.error(e); }); } /** * Renders a push which, when selected, will open a popup for logout */ consign const SignOutButton = () => { const { instance } = useMsal(); return ( <Push variant="secondary" className="ml-auto" onClick={() => handleLogout(instance)}>Sign out using Popup</Button> ); }
Sign out using redirects
Add the post-obit code to src/components/SignOutButton.jsx to create a push button component that will invoke a redirect logout when selected:
import React from "react"; import { useMsal } from "@azure/msal-react"; import Button from "react-bootstrap/Button"; function handleLogout(instance) { instance.logoutRedirect().take hold of(e => { console.fault(e); }); } /** * Renders a push button which, when selected, will redirect the page to the logout prompt */ export const SignOutButton = () => { const { instance } = useMsal(); return ( <Button variant="secondary" className="ml-auto" onClick={() => handleLogout(instance)}>Sign out using Redirect</Button> ); }
Add the sign-out button
Update your PageLayout
component in src/components/PageLayout.jsx to render the new SignOutButton
component for authenticated users. Your code should look like this:
import React from "react"; import Navbar from "react-bootstrap/Navbar"; import { useIsAuthenticated } from "@azure/msal-react"; import { SignInButton } from "./SignInButton"; import { SignOutButton } from "./SignOutButton"; /** * Renders the navbar component with a sign-in push if a user is not authenticated */ export const PageLayout = (props) => { const isAuthenticated = useIsAuthenticated(); render ( <> <Navbar bg="primary" variant="night"> <a className="navbar-brand" href="/">MSAL React Tutorial</a> { isAuthenticated ? <SignOutButton /> : <SignInButton /> } </Navbar> <h5><eye>Welcome to the Microsoft Authentication Library For React Tutorial</eye></h5> <br /> <br /> {props.children} </> ); };
Conditionally return components
In society to render certain components simply for authenticated or unauthenticated users use the AuthenticateTemplate
and/or UnauthenticatedTemplate
as demonstrated below.
-
Add the post-obit import to src/App.js:
import { AuthenticatedTemplate, UnauthenticatedTemplate } from "@azure/msal-react";
-
In social club to render certain components only for authenticated users update your
App
function in src/App.js with the following lawmaking:part App() { return ( <PageLayout> <AuthenticatedTemplate> <p>Yous are signed in!</p> </AuthenticatedTemplate> </PageLayout> ); }
-
To render certain components only for unauthenticated users, such equally a proffer to login, update your
App
office in src/App.js with the following code:role App() { return ( <PageLayout> <AuthenticatedTemplate> <p>You are signed in!</p> </AuthenticatedTemplate> <UnauthenticatedTemplate> <p>You are not signed in! Please sign in.</p> </UnauthenticatedTemplate> </PageLayout> ); }
Acquire a token
-
Earlier calling an API, such every bit Microsoft Graph, y'all'll need to learn an access token. Add a new component to src/App.js called
ProfileContent
with the following code:role ProfileContent() { const { instance, accounts, inProgress } = useMsal(); const [accessToken, setAccessToken] = useState(zilch); const name = accounts[0] && accounts[0].name; office RequestAccessToken() { const asking = { ...loginRequest, account: accounts[0] }; // Silently acquires an access token which is then attached to a request for Microsoft Graph data example.acquireTokenSilent(request).then((response) => { setAccessToken(response.accessToken); }).take hold of((e) => { instance.acquireTokenPopup(asking).and then((response) => { setAccessToken(response.accessToken); }); }); } render ( <> <h5 className="card-title">Welcome {name}</h5> {accessToken ? <p>Access Token Acquired!</p> : <Push variant="secondary" onClick={RequestAccessToken}>Request Access Token</Button> } </> ); };
-
Update your imports in src/App.js to match the following:
import React, { useState } from "react"; import { PageLayout } from "./components/PageLayout"; import { AuthenticatedTemplate, UnauthenticatedTemplate, useMsal } from "@azure/msal-react"; import { loginRequest } from "./authConfig"; import Push button from "react-bootstrap/Push";
-
Finally, add your new
ProfileContent
component as a kid of theAuthenticatedTemplate
in yourApp
component in src/App.js. YourApp
component should await like this:part App() { return ( <PageLayout> <AuthenticatedTemplate> <ProfileContent /> </AuthenticatedTemplate> <UnauthenticatedTemplate> <p>Yous are non signed in! Delight sign in.</p> </UnauthenticatedTemplate> </PageLayout> ); }
The code above will render a push button for signed in users, allowing them to request an admission token for Microsoft Graph when the button is selected.
After a user signs in, your app shouldn't ask users to reauthenticate every time they demand to admission a protected resource (that is, to request a token). To prevent such reauthentication requests, call acquireTokenSilent
which will first look for a cached, unexpired admission token so, if needed, apply the refresh token to obtain a new access token. There are some situations, however, where yous might need to force users to collaborate with the Microsoft identity platform. For example:
- Users demand to re-enter their credentials because the session has expired.
- The refresh token has expired.
- Your application is requesting access to a resource and y'all need the user's consent.
- Two-factor hallmark is required.
Calling acquireTokenPopup
opens a pop-upwardly window (or acquireTokenRedirect
redirects users to the Microsoft identity platform). In that window, users demand to interact past confirming their credentials, giving consent to the required resource, or completing the 2-factor authentication.
Annotation
If you're using Internet Explorer, nosotros recommend that you use the loginRedirect
and acquireTokenRedirect
methods due to a known outcome with Internet Explorer and pop-up windows.
Telephone call the Microsoft Graph API
-
Create file named graph.js in the src folder and add the following lawmaking for making Residuum calls to the Microsoft Graph API:
import { graphConfig } from "./authConfig"; /** * Attaches a given access token to a Microsoft Graph API call. Returns data about the user */ export async function callMsGraph(accessToken) { const headers = new Headers(); const bearer = `Bearer ${accessToken}`; headers.append("Authorization", bearer); const options = { method: "GET", headers: headers }; return fetch(graphConfig.graphMeEndpoint, options) .so(response => response.json()) .catch(fault => panel.log(error)); }
-
Next create a file named ProfileData.jsx in src/components and add the following code:
import React from "react"; /** * Renders data virtually the user obtained from Microsoft Graph */ export const ProfileData = (props) => { render ( <div id="profile-div"> <p><potent>First Proper name: </strong> {props.graphData.givenName}</p> <p><strong>Last Name: </strong> {props.graphData.surname}</p> <p><strong>Email: </stiff> {props.graphData.userPrincipalName}</p> <p><strong>Id: </stiff> {props.graphData.id}</p> </div> ); };
-
Next, open src/App.js and add these to the imports:
import { ProfileData } from "./components/ProfileData"; import { callMsGraph } from "./graph";
-
Finally, update your
ProfileContent
component in src/App.js to call Microsoft Graph and display the contour data afterwards acquiring the token. YourProfileContent
component should look like this:office ProfileContent() { const { case, accounts } = useMsal(); const [graphData, setGraphData] = useState(nada); const name = accounts[0] && accounts[0].name; role RequestProfileData() { const request = { ...loginRequest, account: accounts[0] }; // Silently acquires an access token which is then attached to a request for Microsoft Graph information instance.acquireTokenSilent(request).then((response) => { callMsGraph(response.accessToken).and then(response => setGraphData(response)); }).grab((e) => { instance.acquireTokenPopup(request).and then((response) => { callMsGraph(response.accessToken).so(response => setGraphData(response)); }); }); } return ( <> <h5 className="card-title">Welcome {name}</h5> {graphData ? <ProfileData graphData={graphData} /> : <Button variant="secondary" onClick={RequestProfileData}>Asking Profile Data</Button> } </> ); };
In the changes made above, the callMSGraph()
method is used to brand an HTTP GET
request against a protected resources that requires a token. The asking so returns the content to the caller. This method adds the acquired token in the HTTP Potency header. In the sample application created in this tutorial, the protected resource is the Microsoft Graph API me endpoint which displays the signed-in user's profile data.
Test your application
You've completed creation of the application and are now ready to launch the web server and examination the app's functionality.
-
Serve your app past running the following command from inside the root of your project binder:
npm start
-
A browser window should be opened to your app automatically. If it does not, open your browser and navigate to
http://localhost:3000
. You should see a page that looks like the one beneath. -
Select the sign-in button to sign in.
Provide consent for application access
The commencement fourth dimension yous sign in to your awarding, yous're prompted to grant it access to your profile and sign you lot in:
If you consent to the requested permissions, the spider web applications displays your name, signifying a successful login:
Call the Graph API
After you sign in, select See Contour to view the user profile data returned in the response from the telephone call to the Microsoft Graph API:
More than information almost scopes and delegated permissions
The Microsoft Graph API requires the user.read scope to read a user's profile. Past default, this scope is automatically added in every awarding that's registered in the Azure portal. Other APIs for Microsoft Graph, as well as custom APIs for your dorsum-stop server, might crave boosted scopes. For instance, the Microsoft Graph API requires the Mail.Read telescopic in society to list the user's e-mail.
As you add together scopes, your users might exist prompted to provide additional consent for the added scopes.
Assist and back up
If yous demand help, desire to report an issue, or want to larn about your back up options, see Help and back up for developers.
Next steps
If yous'd like to swoop deeper into JavaScript unmarried-page application evolution on the Microsoft identity platform, meet our multi-role scenario series:
Feedback
Source: https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-react
0 Response to "Reading a Token From Url in React"
Post a Comment