Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Gäller för:
Externa klienter (läs mer)
Den här artikeln är del 2 i en serie som visar hur du lägger till profilredigeringslogik i en Node.js webbapp. I del 1 i den här serienkonfigurerar du appen för profilredigering.
I den här guiden får du lära dig hur du anropar Microsoft Graph API för profilredigering.
Förutsättningar
- Slutför stegen i den andra delen av den här guideserien Konfigurera ett Node.js webbprogram för profilredigering.
Slutför klientwebbappen
I det här avsnittet lägger du till identitetsrelaterad kod för klientwebbappen.
Uppdatera authConfig.js-filen
Uppdatera authConfig.js-filen för klientwebbappen:
Öppna filen App/authConfig.js i kodredigeraren och lägg sedan till tre nya variabler,
GRAPH_API_ENDPOINT,GRAPH_ME_ENDPOINTocheditProfileScope. Se till att exportera de tre variablerna://... const GRAPH_API_ENDPOINT = process.env.GRAPH_API_ENDPOINT || "https://graph.microsoft.com/"; // https://free.blessedness.top/graph/api/user-update?tabs=http const GRAPH_ME_ENDPOINT = GRAPH_API_ENDPOINT + "v1.0/me"; const editProfileScope = process.env.EDIT_PROFILE_FOR_CLIENT_WEB_APP || 'api://{clientId}/EditProfileService.ReadWrite'; module.exports = { //... editProfileScope, GRAPH_API_ENDPOINT, GRAPH_ME_ENDPOINT, //... };Variabeln
editProfileScoperepresenterar MFA-skyddad resurs, dvs. mellannivåappen (EditProfileService-appen).GRAPH_ME_ENDPOINTär Microsoft Graph API-slutpunkten.
Ersätt platshållaren
{clientId}med program-ID:t (klient) för den mellannivåapp (EditProfileService-app) som du registrerade tidigare.
Hämta åtkomsttoken i klientwebbappen
Öppna filen App/auth/AuthProvider.js i kodredigeraren och uppdatera sedan metoden getToken i klassen AuthProvider:
class AuthProvider {
//...
getToken(scopes, redirectUri = "http://localhost:3000/") {
return async function (req, res, next) {
const msalInstance = authProvider.getMsalInstance(authProvider.config.msalConfig);
try {
msalInstance.getTokenCache().deserialize(req.session.tokenCache);
const silentRequest = {
account: req.session.account,
scopes: scopes,
};
const tokenResponse = await msalInstance.acquireTokenSilent(silentRequest);
req.session.tokenCache = msalInstance.getTokenCache().serialize();
req.session.accessToken = tokenResponse.accessToken;
next();
} catch (error) {
if (error instanceof msal.InteractionRequiredAuthError) {
req.session.csrfToken = authProvider.cryptoProvider.createNewGuid();
const state = authProvider.cryptoProvider.base64Encode(
JSON.stringify({
redirectTo: redirectUri,
csrfToken: req.session.csrfToken,
})
);
const authCodeUrlRequestParams = {
state: state,
scopes: scopes,
};
const authCodeRequestParams = {
state: state,
scopes: scopes,
};
authProvider.redirectToAuthCodeUrl(
req,
res,
next,
authCodeUrlRequestParams,
authCodeRequestParams,
msalInstance
);
}
next(error);
}
};
}
}
//...
Metoden getToken använder det angivna omfånget för att hämta en åtkomsttoken. Parametern redirectUri är omdirigerings-URL:en när appen har hämtat en åtkomsttoken.
Uppdatera filen users.js
Öppna filen App/routes/users.js i kodredigeraren och lägg sedan till följande vägar:
//...
var { fetch } = require("../fetch");
const { GRAPH_ME_ENDPOINT, editProfileScope } = require('../authConfig');
//...
router.get(
"/gatedUpdateProfile",
isAuthenticated,
authProvider.getToken(["User.Read"]), // check if user is authenticated
async function (req, res, next) {
const graphResponse = await fetch(
GRAPH_ME_ENDPOINT,
req.session.accessToken,
);
if (!graphResponse.id) {
return res
.status(501)
.send("Failed to fetch profile data");
}
res.render("gatedUpdateProfile", {
profile: graphResponse,
});
},
);
router.get(
"/updateProfile",
isAuthenticated, // check if user is authenticated
authProvider.getToken(
["User.Read", editProfileScope],
"http://localhost:3000/users/updateProfile",
),
async function (req, res, next) {
const graphResponse = await fetch(
GRAPH_ME_ENDPOINT,
req.session.accessToken,
);
if (!graphResponse.id) {
return res
.status(501)
.send("Failed to fetch profile data");
}
res.render("updateProfile", {
profile: graphResponse,
});
},
);
router.post(
"/update",
isAuthenticated,
authProvider.getToken([editProfileScope]),
async function (req, res, next) {
try {
if (!!req.body) {
let body = req.body;
fetch(
"http://localhost:3001/updateUserInfo",
req.session.accessToken,
"POST",
{
displayName: body.displayName,
givenName: body.givenName,
surname: body.surname,
},
)
.then((response) => {
if (response.status === 204) {
return res.redirect("/");
} else {
next("Not updated");
}
})
.catch((error) => {
console.log("error,", error);
});
} else {
throw { error: "empty request" };
}
} catch (error) {
next(error);
}
},
);
//...
Du aktiverar
/gatedUpdateProfilerutten när kunden väljer länken Profilredigering. Appen:- Hämtar en åtkomsttoken med behörigheten User.Read.
- Anropar Microsoft Graph API för att läsa den inloggade användarens profil.
- Visar användarinformationen i gatedUpdateProfile.hbs användargränssnittet.
Du utlöser rutten
/updateProfilenär användaren vill uppdatera sitt visningsnamn, det vill säga när de väljer knappen Redigera profil. Appen:- Gör ett anrop till mellannivåappen (EditProfileService-appen) med editProfileScope omfång. Genom att göra ett anrop till mellannivåappen (EditProfileService-appen) måste användaren slutföra en MFA-utmaning om de inte redan har gjort det.
- Visar användarinformationen i updateProfile.hbs användargränssnittet.
Du aktiverar
/update-rutten när användaren väljer knappen Spara i antingen gatedUpdateProfile.hbs eller updateProfile.hbs. Appen:- Hämtar åtkomsttoken för appsessionen. Du lär dig hur mellannivåappen (EditProfileService-appen) hämtar åtkomsttoken i nästa avsnitt.
- Samlar in all användarinformation.
- Anropar Microsoft Graph API för att uppdatera användarens profil.
Uppdatera filen fetch.js
Appen använder filen App/fetch.js för att göra de faktiska API-anropen.
Öppna App/fetch.js-filen i kodredigeraren och lägg sedan till alternativet PATCH-åtgärd. När du har uppdaterat filen bör den resulterande filen se ut ungefär som följande kod:
var axios = require('axios');
var authProvider = require("./auth/AuthProvider");
/**
* Makes an Authorization "Bearer" request with the given accessToken to the given endpoint.
* @param endpoint
* @param accessToken
* @param method
*/
const fetch = async (endpoint, accessToken, method = "GET", data = null) => {
const options = {
headers: {
Authorization: `Bearer ${accessToken}`,
},
};
console.log(`request made to ${endpoint} at: ` + new Date().toString());
switch (method) {
case 'GET':
const response = await axios.get(endpoint, options);
return await response.data;
case 'POST':
return await axios.post(endpoint, data, options);
case 'DELETE':
return await axios.delete(endpoint + `/${data}`, options);
case 'PATCH':
return await axios.patch(endpoint, ReqBody = data, options);
default:
return null;
}
};
module.exports = { fetch };
Slutför mellannivåappen
I det här avsnittet lägger du till den identitetsrelaterade koden för mellannivåappen (EditProfileService-appen).
Öppna Api/authConfig.js-fil i kodredigeraren och lägg sedan till följande kod:
require("dotenv").config({ path: ".env.dev" }); const TENANT_SUBDOMAIN = process.env.TENANT_SUBDOMAIN || "Enter_the_Tenant_Subdomain_Here"; const TENANT_ID = process.env.TENANT_ID || "Enter_the_Tenant_ID_Here"; const REDIRECT_URI = process.env.REDIRECT_URI || "http://localhost:3000/auth/redirect"; const POST_LOGOUT_REDIRECT_URI = process.env.POST_LOGOUT_REDIRECT_URI || "http://localhost:3000"; /** * Configuration object to be passed to MSAL instance on creation. * For a full list of MSAL Node configuration parameters, visit: * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/docs/configuration.md */ const msalConfig = { auth: { clientId: process.env.CLIENT_ID || "Enter_the_Edit_Profile_Service_Application_Id_Here", // 'Application (client) ID' of the Edit_Profile Service App registration in Microsoft Entra admin center - this value is a GUID authority: process.env.AUTHORITY || `https://${TENANT_SUBDOMAIN}.ciamlogin.com/`, // Replace the placeholder with your external tenant name clientSecret: process.env.CLIENT_SECRET || "Enter_the_Client_Secret_Here ", // Client secret generated from the app registration in Microsoft Entra admin center }, system: { loggerOptions: { loggerCallback(loglevel, message, containsPii) { console.log(message); }, piiLoggingEnabled: false, logLevel: "Info", }, }, }; const GRAPH_API_ENDPOINT = process.env.GRAPH_API_ENDPOINT || "graph_end_point"; // Refers to the user that is single user singed in. // https://free.blessedness.top/en-us/graph/api/user-update?tabs=http const GRAPH_ME_ENDPOINT = GRAPH_API_ENDPOINT + "v1.0/me"; module.exports = { msalConfig, REDIRECT_URI, POST_LOGOUT_REDIRECT_URI, TENANT_SUBDOMAIN, GRAPH_API_ENDPOINT, GRAPH_ME_ENDPOINT, TENANT_ID, };Hitta platshållaren:
-
Enter_the_Tenant_Subdomain_Hereoch ersätt det med Katalog (klientorganisation) underdomän. Om din primära klientdomän till exempel ärcontoso.onmicrosoft.comanvänder ducontoso. Om du inte har ditt klientnamn, lär dig hur du kan läsa klientinformationen. -
Enter_the_Tenant_ID_Hereoch ersätt det med tenant-ID. Om du inte har ditt klient-ID, lär dig hur du läser dina klientdetaljer. -
Enter_the_Edit_Profile_Service_Application_Id_Hereoch ersätt det med applikationens (klientens) ID-värde för den EditProfileService som du registrerade tidigare. -
Enter_the_Client_Secret_Hereoch ersätt den med EditProfileService-apphemligheten värde som du kopierade tidigare. -
graph_end_pointoch ersätt den med Microsoft Graph API-slutpunkten, som ärhttps://graph.microsoft.com/.
-
Öppna Api/fetch.js-filen i kodredigeraren och klistra sedan in koden från Api/fetch.js-filen. Funktionen
fetchanvänder en åtkomsttoken och resursslutpunkten för att göra det faktiska API-anropet.Öppna Api/index.js-filen i kodredigeraren och klistra sedan in koden från Api/index.js-filen.
Hämta en åtkomsttoken med hjälp av acquireTokenOnBehalfOf
I filen Api/index.js hämtar mellannivåappen (EditProfileService-appen) en åtkomsttoken med hjälp av funktionen acquireTokenOnBehalfOf, som används för att uppdatera profilen åt användaren.
async function getAccessToken(tokenRequest) {
try {
const response = await cca.acquireTokenOnBehalfOf(tokenRequest);
return response.accessToken;
} catch (error) {
console.error("Error acquiring token:", error);
throw error;
}
}
Parametern tokenRequest definieras enligt följande kod:
const tokenRequest = {
oboAssertion: req.headers.authorization.replace("Bearer ", ""),
authority: `https://${TENANT_SUBDOMAIN}.ciamlogin.com/${TENANT_ID}`,
scopes: ["User.ReadWrite"],
correlationId: `${uuidv4()}`,
};
I samma fil anropar API/index.js, appen på mellannivå (EditProfileService-appen) ett anrop till Microsoft Graph API för att uppdatera användarens profil:
let accessToken = await getAccessToken(tokenRequest);
fetch(GRAPH_ME_ENDPOINT, accessToken, "PATCH", req.body)
.then((response) => {
if (response.status === 204) {
res.status(response.status);
res.json({ message: "Success" });
} else {
res.status(502);
res.json({ message: "Failed, " + response.body });
}
})
.catch((error) => {
res.status(502);
res.json({ message: "Failed, " + error });
});
Testa din app
Använd följande steg för att testa din app:
Om du vill köra klientappen skapar du terminalfönstret, navigerar till katalogen App och kör sedan följande kommando:
npm startOm du vill köra klientappen skapar du terminalfönstret, navigerar till katalogen API och kör sedan följande kommando:
npm startÖppna webbläsaren och gå sedan till http://localhost:3000. Om du får SSL-certifikatfel skapar du en
.env-fil och lägger sedan till följande konfiguration:# Use this variable only in the development environment. # Remove the variable when you move the app to the production environment. NODE_TLS_REJECT_UNAUTHORIZED='0'Välj knappen Logga in, och därefter loggar du in.
På inloggningssidan skriver du din e-postadress, väljer Nästa, skriver Lösenordoch väljer sedan Logga in. Om du inte har något konto väljer du Inget konto? Skapa en länk som startar registreringsflödet.
Om du vill uppdatera profilen väljer du länken Profilredigering. Du ser en sida som liknar följande skärmbild:
Om du vill redigera profilen väljer du knappen Redigera profil. Om du inte redan har gjort det uppmanar appen dig att slutföra en MFA-utmaning.
Gör ändringar i någon av profilinformationen och välj sedan knappen Spara.