빠른 시작: SPA(단일 페이지 앱)에서 사용자를 로그인하고 Microsoft Graph API를 호출합니다.
아티클
이 빠른 시작에서는 샘플 SPA(단일 페이지 앱)를 사용하여 PKCE(Proof Key for Code Exchange)와 함께 인증 코드 흐름 사용하여 사용자를 로그인하고 Microsoft Graph API를 호출하는 방법을 보여 줍니다. 이 샘플에서는 Microsoft 인증 라이브러리 사용하여 인증을 처리합니다.
IDE에서 샘플이 포함된 ms-identity-docs-code-javascript 프로젝트 폴더를 엽니다.
vanillajs-spa/App/public/authConfig.js 열고 관리 센터에 기록된 정보로 다음 값을 업데이트합니다.
/**
* Configuration object to be passed to MSAL instance on creation.
* For a full list of MSAL.js configuration parameters, visit:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/configuration.md
*/
const msalConfig = {
auth: {
// WORKFORCE TENANT
authority: "https://login.microsoftonline.com/Enter_the_Tenant_Info_Here", // Replace the placeholder with your tenant info
// EXTERNAL TENANT
// authority: "https://Enter_the_Tenant_Subdomain_Here.ciamlogin.com/", // Replace the placeholder with your tenant subdomain
redirectUri: '/', // You must register this URI on App Registration. Defaults to window.location.href e.g. http://localhost:3000/
navigateToLoginRequestUrl: true, // If "true", will navigate back to the original request location before processing the auth code response.
},
cache: {
cacheLocation: 'sessionStorage', // Configures cache location. "sessionStorage" is more secure, but "localStorage" gives you SSO.
storeAuthStateInCookie: false, // set this to true if you have to support IE
},
system: {
loggerOptions: {
loggerCallback: (level, message, containsPii) => {
if (containsPii) {
return;
}
switch (level) {
case msal.LogLevel.Error:
console.error(message);
return;
case msal.LogLevel.Info:
console.info(message);
return;
case msal.LogLevel.Verbose:
console.debug(message);
return;
case msal.LogLevel.Warning:
console.warn(message);
return;
}
},
},
},
};
/**
* Scopes you add here will be prompted for user consent during sign-in.
* By default, MSAL.js will add OIDC scopes (openid, profile, email) to any login request.
* For more information about OIDC scopes, visit:
* https://learn.microsoft.com/en-us/entra/identity-platform/permissions-consent-overview#openid-connect-scopes
* https://learn.microsoft.com/en-us/entra/identity-platform/permissions-consent-overview#openid-connect-scopes
*/
const loginRequest = {
scopes: ["User.Read"],
};
/**
* An optional silentRequest object can be used to achieve silent SSO
* between applications by providing a "login_hint" property.
*/
// const silentRequest = {
// scopes: ["openid", "profile"],
// loginHint: "example@domain.net"
// };
// exporting config object for jest
if (typeof exports !== 'undefined') {
module.exports = {
msalConfig: msalConfig,
loginRequest: loginRequest,
};
module.exports = {
msalConfig: msalConfig,
loginRequest: loginRequest,
};
}
clientId - 클라이언트라고도 하는 애플리케이션의 식별자입니다. 따옴표의 텍스트를 이전에 기록된 애플리케이션(클라이언트) ID 값으로 바꿉니다.
authority - 권한은 MSAL이 토큰을 요청할 수 있는 디렉터리를 나타내는 URL입니다.
Enter_the_Tenant_Info_Here 이전에 기록된 디렉터리(테넌트) ID 값으로 바꿉니다.
redirectUri - 애플리케이션의 리디렉션 URI. 필요한 경우 따옴표로 된 텍스트를 이전에 기록된 리디렉션 URI로 바꿉니다.
IDE에서 샘플이 포함된 ms-identity-docs-code-javascript/react-spa 프로젝트 폴더를 엽니다.
react-spa/src/authConfig.js 열고 관리 센터에 기록된 정보로 다음 값을 업데이트합니다.
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import { LogLevel } from "@azure/msal-browser";
/**
* Configuration object to be passed to MSAL instance on creation.
* For a full list of MSAL.js configuration parameters, visit:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/configuration.md
*/
export const msalConfig = {
auth: {
clientId: "Enter_the_Application_Id_Here",
authority: "https://login.microsoftonline.com/Enter_the_Tenant_Info_Here",
redirectUri: "http://localhost:3000",
},
cache: {
cacheLocation: "sessionStorage", // This configures where your cache will be stored
storeAuthStateInCookie: false, // Set this to "true" if you are having issues on IE11 or Edge
},
system: {
loggerOptions: {
loggerCallback: (level, message, containsPii) => {
if (containsPii) {
return;
}
switch (level) {
case LogLevel.Error:
console.error(message);
return;
case LogLevel.Info:
console.info(message);
return;
case LogLevel.Verbose:
console.debug(message);
return;
case LogLevel.Warning:
console.warn(message);
return;
default:
return;
}
}
}
}
};
/**
* Scopes you add here will be prompted for user consent during sign-in.
* By default, MSAL.js will add OIDC scopes (openid, profile, email) to any login request.
* For more information about OIDC scopes, visit:
* https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
*/
export const loginRequest = {
scopes: ["User.Read"]
};
/**
* Add here the scopes to request when obtaining an access token for MS Graph API. For more information, see:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/resources-and-scopes.md
*/
export const graphConfig = {
graphMeEndpoint: "https://graph.microsoft.com/v1.0/me",
};
clientId - 클라이언트라고도 하는 애플리케이션의 식별자입니다. 따옴표의 텍스트를 이전에 기록된 애플리케이션(클라이언트) ID 값으로 바꿉니다.
authority - 권한은 MSAL이 토큰을 요청할 수 있는 디렉터리의 URL을 나타냅니다.
Enter_the_Tenant_Info_Here 이전에 기록된 디렉터리(테넌트) ID 값으로 바꿉니다.
redirectUri - 애플리케이션의 리디렉션 URI. 필요한 경우 따옴표로 된 텍스트를 이전에 기록된 리디렉션 URI로 바꿉니다.
IDE에서 샘플이 포함된 ms-identity-docs-code-javascript/angular-spa 프로젝트 폴더를 엽니다.
angular-spa/src/app/app.module.ts 열고 관리 센터에 기록된 정보로 다음 값을 업데이트합니다.
// Required for Angular multi-browser support
import { BrowserModule } from '@angular/platform-browser';
// Required for Angular
import { NgModule } from '@angular/core';
// Required modules and components for this application
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ProfileComponent } from './profile/profile.component';
import { HomeComponent } from './home/home.component';
// HTTP modules required by MSAL
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
// Required for MSAL
import { IPublicClientApplication, PublicClientApplication, InteractionType, BrowserCacheLocation, LogLevel } from '@azure/msal-browser';
import { MsalGuard, MsalInterceptor, MsalBroadcastService, MsalInterceptorConfiguration, MsalModule, MsalService, MSAL_GUARD_CONFIG, MSAL_INSTANCE, MSAL_INTERCEPTOR_CONFIG, MsalGuardConfiguration, MsalRedirectComponent } from '@azure/msal-angular';
const isIE = window.navigator.userAgent.indexOf('MSIE ') > -1 || window.navigator.userAgent.indexOf('Trident/') > -1;
export function MSALInstanceFactory(): IPublicClientApplication {
return new PublicClientApplication({
auth: {
// 'Application (client) ID' of app registration in the Microsoft Entra admin center - this value is a GUID
clientId: "Enter_the_Application_Id_Here",
// Full directory URL, in the form of https://login.microsoftonline.com/<tenant>
authority: "https://login.microsoftonline.com/Enter_the_Tenant_Info_Here",
// Must be the same redirectUri as what was provided in your app registration.
redirectUri: "http://localhost:4200",
},
cache: {
cacheLocation: BrowserCacheLocation.LocalStorage,
storeAuthStateInCookie: isIE
}
});
}
// MSAL Interceptor is required to request access tokens in order to access the protected resource (Graph)
export function MSALInterceptorConfigFactory(): MsalInterceptorConfiguration {
const protectedResourceMap = new Map<string, Array<string>>();
protectedResourceMap.set('https://graph.microsoft.com/v1.0/me', ['user.read']);
return {
interactionType: InteractionType.Redirect,
protectedResourceMap
};
}
// MSAL Guard is required to protect routes and require authentication before accessing protected routes
export function MSALGuardConfigFactory(): MsalGuardConfiguration {
return {
interactionType: InteractionType.Redirect,
authRequest: {
scopes: ['user.read']
}
};
}
// Create an NgModule that contains the routes and MSAL configurations
@NgModule({
declarations: [
AppComponent,
HomeComponent,
ProfileComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
MsalModule
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: MsalInterceptor,
multi: true
},
{
provide: MSAL_INSTANCE,
useFactory: MSALInstanceFactory
},
{
provide: MSAL_GUARD_CONFIG,
useFactory: MSALGuardConfigFactory
},
{
provide: MSAL_INTERCEPTOR_CONFIG,
useFactory: MSALInterceptorConfigFactory
},
MsalService,
MsalGuard,
MsalBroadcastService
],
bootstrap: [AppComponent, MsalRedirectComponent]
})
export class AppModule { }
clientId - 클라이언트라고도 하는 애플리케이션의 식별자입니다. 따옴표의 텍스트를 이전에 기록된 애플리케이션(클라이언트) ID 값으로 바꿉니다.
authority - 기관은 MSAL이 토큰을 요청할 수 있는 디렉터리를 나타내는 URL입니다.
Enter_the_Tenant_Info_Here 이전에 기록된 디렉터리(테넌트) ID 값으로 바꿉니다.
redirectUri - 애플리케이션의 리디렉션 URI. 필요한 경우 따옴표로 된 텍스트를 이전에 기록된 리디렉션 URI로 바꿉니다.
IDE에서 샘플이 포함된 ms-identity-docs-code-dotnet/spa-blazor-wasm 프로젝트 폴더를 엽니다.
spa-blazor-wasm/wwwroot/appsettings.json 열고 관리 센터에서 이전에 기록된 정보로 다음 값을 업데이트합니다.
{
"AzureAd": {
"Authority": "https://login.microsoftonline.com/<Enter the tenant ID obtained from the Microsoft Entra admin center>",
"ClientId": "Enter the client ID obtained from the Microsoft Entra admin center",
"ValidateAuthority": true
}
}
Authority - 권한은 MSAL이 토큰을 요청할 수 있는 디렉터리를 나타내는 URL입니다.
Enter_the_Tenant_Info_Here 이전에 기록된 디렉터리(테넌트) ID 값으로 바꿉니다.
ClientId - 클라이언트라고도 하는 애플리케이션의 식별자입니다. 따옴표의 텍스트를 이전에 기록된 애플리케이션(클라이언트) ID 값으로 바꿉니다.
터미널에 표시되는 https URL(예: https://localhost:3000)을 복사하여 브라우저에 붙여넣습니다. 프라이빗 또는 시크릿 브라우저 세션을 사용하는 것이 좋습니다.
단계를 수행하고 필요한 세부 정보를 입력하여 Microsoft 계정으로 로그인합니다. 한 번 암호를 보낼 수 있도록 전자 메일 주소를 요청합니다. 메시지가 표시되면 코드를 입력합니다.
애플리케이션은 액세스 권한을 부여한 데이터에 대한 액세스를 유지하고 로그인하여 프로필을 읽을 수 있는 권한을 요청합니다.
수락선택합니다. 애플리케이션에 로그인하고 Microsoft Graph API에서 프로필 세부 정보에 액세스했음을 나타내는 다음 스크린샷이 나타납니다.
Node.js사용하여 웹 서버에서 프로젝트를 실행합니다.
서버를 시작하려면 프로젝트 디렉터리 내에서 다음 명령을 실행합니다.
cd react-spa/App
npm install
npm start
터미널에 표시되는 https URL(예: https://localhost:3000)을 복사하여 브라우저에 붙여넣습니다. 프라이빗 또는 시크릿 브라우저 세션을 사용하는 것이 좋습니다.
단계를 수행하고 필요한 세부 정보를 입력하여 Microsoft 계정으로 로그인합니다. 한 번 암호를 보낼 수 있도록 전자 메일 주소를 요청합니다. 메시지가 표시되면 코드를 입력합니다.
애플리케이션은 액세스 권한을 부여한 데이터에 대한 액세스를 유지하고 로그인하여 프로필을 읽을 수 있는 권한을 요청합니다.
을 선택하고을 수락합니다. 애플리케이션에 로그인하고 Microsoft Graph API에서 프로필 세부 정보에 액세스했음을 나타내는 다음 스크린샷이 나타납니다.
Node.js사용하여 웹 서버에서 프로젝트를 실행합니다.
서버를 시작하려면 프로젝트 디렉터리 내에서 다음 명령을 실행합니다.
cd angular-spa/App
npm install
npm start
터미널에 표시되는 https URL(예: https://localhost:4200)을 복사하여 브라우저 주소 표시줄에 붙여넣습니다. 프라이빗 또는 시크릿 브라우저 세션을 사용하는 것이 좋습니다.
단계를 수행하고 필요한 세부 정보를 입력하여 Microsoft 계정으로 로그인합니다. 한 번 암호를 보낼 수 있도록 전자 메일 주소를 요청합니다. 메시지가 표시되면 코드를 입력합니다.
애플리케이션은 액세스 권한을 부여한 데이터에 대한 액세스를 유지하고 로그인하여 프로필을 읽을 수 있는 권한을 요청합니다.
수락을 선택합니다. 애플리케이션에 로그인하고 Microsoft Graph API에서 프로필 세부 정보에 액세스했음을 나타내는 다음 스크린샷이 나타납니다.
dotnet을 사용하여 웹 서버에서 프로젝트를 실행합니다.
서버를 시작하려면 프로젝트 디렉터리 내에서 다음 명령을 실행합니다.
cd spa-blazor-wasm
dotnet workload install wasm-tools
dotnet run
터미널에 표시되는 http URL(예: http://localhost:5000)을 복사하여 브라우저에 붙여넣습니다. 프라이빗 또는 시크릿 브라우저 세션을 사용하는 것이 좋습니다.
단계를 수행하고 필요한 세부 정보를 입력하여 Microsoft 계정으로 로그인합니다. 한 번 암호를 보낼 수 있도록 전자 메일 주소를 요청합니다. 메시지가 표시되면 코드를 입력합니다.
애플리케이션은 액세스 권한을 부여한 데이터에 대한 액세스를 유지하고 로그인하여 프로필을 읽을 수 있는 권한을 요청합니다.
수락을 선택합니다. 애플리케이션에 로그인하고 Microsoft Graph API에서 프로필 세부 정보에 액세스했음을 나타내는 다음 스크린샷이 나타납니다.
애플리케이션이 Microsoft Entra를 사용하여 사용자를 로그인할 수 있도록 하려면 사용자가 만든 애플리케이션을 Microsoft Entra 외부 ID로 인식해야 합니다. 앱 등록은 앱과 Microsoft Entra 간에 트러스트 관계를 설정합니다. 애플리케이션을 등록할 때 외부 ID는 인증 요청을 만들 때 앱을 식별하는 데 사용되는 값인 애플리케이션(클라이언트) ID알려진 고유 식별자를 생성합니다.
다음 단계에서는 Microsoft Entra 관리 센터에서 앱을 등록하는 방법을 보여 줍니다.
App/public/authConfig.js 열고 다음을 Microsoft Entra 관리 센터에서 가져온 값으로 바꿉다.
Enter_the_Application_Id_Here 이전에 등록한 앱의 애플리케이션(클라이언트) ID로 바꿉니다.
Enter_the_Tenant_Subdomain_Here 디렉터리(테넌트) 하위 도메인으로 바꿉니다. 예를 들어 테넌트 주 도메인이 contoso.onmicrosoft.com경우 contoso사용합니다. 테넌트 이름이 없는 경우 테넌트 세부 정보를 읽는 방법을배우세요.
파일을 저장합니다.
SPA\src\authConfig.js 열고 다음을 Microsoft Entra 관리 센터에서 가져온 값으로 바꿉다.
Enter_the_Application_Id_Here 이전에 등록한 앱의 애플리케이션(클라이언트) ID로 바꿉니다.
Enter_the_Tenant_Subdomain_Here 디렉터리(테넌트) 하위 도메인으로 바꿉니다. 예를 들어 테넌트 주 도메인이 contoso.onmicrosoft.com경우 contoso사용합니다. 테넌트 이름이 없는 경우 테넌트 세부 정보를 읽는 방법을알아봅니다.
파일을 저장합니다.
SPA/src/app/auth-config.ts 열고 다음을 Microsoft Entra 관리 센터에서 가져온 값으로 바꿉다.
Enter_the_Application_Id_Here 이전에 등록한 앱의 애플리케이션(클라이언트) ID로 바꿉니다.
Enter_the_Tenant_Subdomain_Here 디렉터리(테넌트) 하위 도메인으로 바꿉니다. 예를 들어 테넌트 주 도메인이 contoso.onmicrosoft.com경우 contoso사용합니다. 테넌트 이름이 없으면 테넌트 세부 정보를 읽는 방법을알아봅니다.