Skip to content

Instantly share code, notes, and snippets.

@zz-chen
Created April 10, 2018 06:22
Show Gist options
  • Save zz-chen/3472c91744c64dcc809d8ffca8302c09 to your computer and use it in GitHub Desktop.
Save zz-chen/3472c91744c64dcc809d8ffca8302c09 to your computer and use it in GitHub Desktop.
Microsoft app Demo
// Graph API endpoint to show user profile
var graphApiEndpoint = "https://graph.microsoft.com/v1.0/me";
// Graph API scope used to obtain the access token to read user profile
var graphAPIScopes = ["https://graph.microsoft.com/user.read"];
// Initialize application
var userAgentApplication = new Msal.UserAgentApplication(msalconfig.clientID, null, loginCallback, {
redirectUri: msalconfig.redirectUri
});
//Previous version of msal uses redirect url via a property
if (userAgentApplication.redirectUri) {
userAgentApplication.redirectUri = msalconfig.redirectUri;
}
window.onload = function () {
// If page is refreshed, continue to display user info
if (!userAgentApplication.isCallback(window.location.hash) && window.parent === window && !window.opener) {
var user = userAgentApplication.getUser();
if (user) {
callGraphApi();
}
}
}
/**
* Call the Microsoft Graph API and display the results on the page. Sign the user in if necessary
*/
function callGraphApi() {
var user = userAgentApplication.getUser();
if (!user) {
// If user is not signed in, then prompt user to sign in via loginRedirect.
// This will redirect user to the Azure Active Directory v2 Endpoint
userAgentApplication.loginRedirect(graphAPIScopes);
// The call to loginRedirect above frontloads the consent to query Graph API during the sign-in.
// If you want to use dynamic consent, just remove the graphAPIScopes from loginRedirect call.
// As such, user will be prompted to give consent when requested access to a resource that
// he/she hasn't consented before. In the case of this application -
// the first time the Graph API call to obtain user's profile is executed.
} else {
// If user is already signed in, display the user info
var userInfoElement = document.getElementById("userInfo");
userInfoElement.parentElement.classList.remove("hidden");
userInfoElement.innerHTML = JSON.stringify(user, null, 4);
// Show Sign-Out button
document.getElementById("signOutButton").classList.remove("hidden");
// Now Call Graph API to show the user profile information:
var graphCallResponseElement = document.getElementById("graphResponse");
graphCallResponseElement.parentElement.classList.remove("hidden");
graphCallResponseElement.innerText = "Calling Graph ...";
// In order to call the Graph API, an access token needs to be acquired.
// Try to acquire the token used to query Graph API silently first:
userAgentApplication.acquireTokenSilent(graphAPIScopes)
.then(function (token) {
//After the access token is acquired, call the Web API, sending the acquired token
callWebApiWithToken(graphApiEndpoint, token, graphCallResponseElement, document.getElementById("accessToken"));
}, function (error) {
// If the acquireTokenSilent() method fails, then acquire the token interactively via acquireTokenRedirect().
// In this case, the browser will redirect user back to the Azure Active Directory v2 Endpoint so the user
// can reenter the current username/ password and/ or give consent to new permissions your application is requesting.
// After authentication/ authorization completes, this page will be reloaded again and callGraphApi() will be executed on page load.
// Then, acquireTokenSilent will then get the token silently, the Graph API call results will be made and results will be displayed in the page.
if (error) {
userAgentApplication.acquireTokenRedirect(graphAPIScopes);
}
});
}
}
/**
* Callback method from sign-in: if no errors, call callGraphApi() to show results.
* @param {string} errorDesc - If error occur, the error message
* @param {object} token - The token received from login
* @param {object} error - The error string
* @param {string} tokenType - The token type: For loginRedirect, tokenType = "id_token". For acquireTokenRedirect, tokenType:"access_token".
*/
function loginCallback(errorDesc, token, error, tokenType) {
if (errorDesc) {
showError(msal.authority, error, errorDesc);
} else {
callGraphApi();
}
}
/**
* Show an error message in the page
* @param {string} endpoint - the endpoint used for the error message
* @param {string} error - Error string
* @param {string} errorDesc - Error description
*/
function showError(endpoint, error, errorDesc) {
var formattedError = JSON.stringify(error, null, 4);
if (formattedError.length < 3) {
formattedError = error;
}
document.getElementById("errorMessage").innerHTML = "An error has occurred:<br/>Endpoint: " + endpoint + "<br/>Error: " + formattedError + "<br/>" + errorDesc;
console.error(error);
}
/**
* Call a Web API using an access token.
* @param {any} endpoint - Web API endpoint
* @param {any} token - Access token
* @param {object} responseElement - HTML element used to display the results
* @param {object} showTokenElement = HTML element used to display the RAW access token
*/
function callWebApiWithToken(endpoint, token, responseElement, showTokenElement) {
var headers = new Headers();
var bearer = "Bearer " + token;
headers.append("Authorization", bearer);
var options = {
method: "GET",
headers: headers
};
fetch(endpoint, options)
.then(function (response) {
var contentType = response.headers.get("content-type");
if (response.status === 200 && contentType && contentType.indexOf("application/json") !== -1) {
response.json()
.then(function (data) {
// Display response in the page
console.log(data);
responseElement.innerHTML = JSON.stringify(data, null, 4);
if (showTokenElement) {
showTokenElement.parentElement.classList.remove("hidden");
showTokenElement.innerHTML = token;
}
})
.catch(function (error) {
showError(endpoint, error);
});
} else {
response.json()
.then(function (data) {
// Display response as error in the page
showError(endpoint, data);
})
.catch(function (error) {
showError(endpoint, error);
});
}
})
.catch(function (error) {
showError(endpoint, error);
});
}
/**
* Sign-out the user
*/
function signOut() {
userAgentApplication.logout();
}
// Graph API endpoint to show user profile
var graphApiEndpoint = "https://graph.microsoft.com/v1.0/me";
// Graph API scope used to obtain the access token to read user profile
var graphAPIScopes = ["https://graph.microsoft.com/user.read"];
// Initialize application
var userAgentApplication = new Msal.UserAgentApplication(msalconfig.clientID, null, loginCallback, {
redirectUri: msalconfig.redirectUri
});
//Previous version of msal uses redirect url via a property
if (userAgentApplication.redirectUri) {
userAgentApplication.redirectUri = msalconfig.redirectUri;
}
window.onload = function () {
// If page is refreshed, continue to display user info
if (!userAgentApplication.isCallback(window.location.hash) && window.parent === window && !window.opener) {
var user = userAgentApplication.getUser();
if (user) {
callGraphApi();
}
}
}
/**
* Call the Microsoft Graph API and display the results on the page. Sign the user in if necessary
*/
function callGraphApi() {
var user = userAgentApplication.getUser();
if (!user) {
// If user is not signed in, then prompt user to sign in via loginRedirect.
// This will redirect user to the Azure Active Directory v2 Endpoint
userAgentApplication.loginRedirect(graphAPIScopes);
// The call to loginRedirect above frontloads the consent to query Graph API during the sign-in.
// If you want to use dynamic consent, just remove the graphAPIScopes from loginRedirect call.
// As such, user will be prompted to give consent when requested access to a resource that
// he/she hasn't consented before. In the case of this application -
// the first time the Graph API call to obtain user's profile is executed.
} else {
// If user is already signed in, display the user info
var userInfoElement = document.getElementById("userInfo");
userInfoElement.parentElement.classList.remove("hidden");
userInfoElement.innerHTML = JSON.stringify(user, null, 4);
// Show Sign-Out button
document.getElementById("signOutButton").classList.remove("hidden");
// Now Call Graph API to show the user profile information:
var graphCallResponseElement = document.getElementById("graphResponse");
graphCallResponseElement.parentElement.classList.remove("hidden");
graphCallResponseElement.innerText = "Calling Graph ...";
// In order to call the Graph API, an access token needs to be acquired.
// Try to acquire the token used to query Graph API silently first:
userAgentApplication.acquireTokenSilent(graphAPIScopes)
.then(function (token) {
//After the access token is acquired, call the Web API, sending the acquired token
callWebApiWithToken(graphApiEndpoint, token, graphCallResponseElement, document.getElementById("accessToken"));
}, function (error) {
// If the acquireTokenSilent() method fails, then acquire the token interactively via acquireTokenRedirect().
// In this case, the browser will redirect user back to the Azure Active Directory v2 Endpoint so the user
// can reenter the current username/ password and/ or give consent to new permissions your application is requesting.
// After authentication/ authorization completes, this page will be reloaded again and callGraphApi() will be executed on page load.
// Then, acquireTokenSilent will then get the token silently, the Graph API call results will be made and results will be displayed in the page.
if (error) {
userAgentApplication.acquireTokenRedirect(graphAPIScopes);
}
});
}
}
/**
* Callback method from sign-in: if no errors, call callGraphApi() to show results.
* @param {string} errorDesc - If error occur, the error message
* @param {object} token - The token received from login
* @param {object} error - The error string
* @param {string} tokenType - The token type: For loginRedirect, tokenType = "id_token". For acquireTokenRedirect, tokenType:"access_token".
*/
function loginCallback(errorDesc, token, error, tokenType) {
if (errorDesc) {
showError(msal.authority, error, errorDesc);
} else {
callGraphApi();
}
}
/**
* Show an error message in the page
* @param {string} endpoint - the endpoint used for the error message
* @param {string} error - Error string
* @param {string} errorDesc - Error description
*/
function showError(endpoint, error, errorDesc) {
var formattedError = JSON.stringify(error, null, 4);
if (formattedError.length < 3) {
formattedError = error;
}
document.getElementById("errorMessage").innerHTML = "An error has occurred:<br/>Endpoint: " + endpoint + "<br/>Error: " + formattedError + "<br/>" + errorDesc;
console.error(error);
}
/**
* Call a Web API using an access token.
* @param {any} endpoint - Web API endpoint
* @param {any} token - Access token
* @param {object} responseElement - HTML element used to display the results
* @param {object} showTokenElement = HTML element used to display the RAW access token
*/
function callWebApiWithToken(endpoint, token, responseElement, showTokenElement) {
var headers = new Headers();
var bearer = "Bearer " + token;
headers.append("Authorization", bearer);
var options = {
method: "GET",
headers: headers
};
fetch(endpoint, options)
.then(function (response) {
var contentType = response.headers.get("content-type");
if (response.status === 200 && contentType && contentType.indexOf("application/json") !== -1) {
response.json()
.then(function (data) {
// Display response in the page
console.log(data);
responseElement.innerHTML = JSON.stringify(data, null, 4);
if (showTokenElement) {
showTokenElement.parentElement.classList.remove("hidden");
showTokenElement.innerHTML = token;
}
})
.catch(function (error) {
showError(endpoint, error);
});
} else {
response.json()
.then(function (data) {
// Display response as error in the page
showError(endpoint, data);
})
.catch(function (error) {
showError(endpoint, error);
});
}
})
.catch(function (error) {
showError(endpoint, error);
});
}
/**
* Sign-out the user
*/
function signOut() {
userAgentApplication.logout();
}
<!DOCTYPE html>
<html>
<head>
<!-- bootstrap reference used for styling the page -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<title>JavaScript SPA Guided Setup</title>
<meta charset="utf8" />
</head>
<body style="margin: 40px">
<button id="callGraphButton" type="button" class="btn btn-primary" onclick="callGraphApi()">Call Microsoft Graph API</button>
<div id="errorMessage" class="text-danger"></div>
<div class="hidden">
<h3>Graph API Call Response</h3>
<pre class="well" id="graphResponse"></pre>
</div>
<div class="hidden">
<h3>Access Token</h3>
<pre class="well" id="accessToken"></pre>
</div>
<div class="hidden">
<h3>ID Token Claims</h3>
<pre class="well" id="userInfo"></pre>
</div>
<button id="signOutButton" type="button" class="btn btn-primary hidden" onclick="signOut()">Sign out</button>
<!-- This app uses cdn to reference msal.js (recommended).
You can also download it from: https://github.com/AzureAD/microsoft-authentication-library-for-js -->
<script src="https://secure.aadcdn.microsoftonline-p.com/lib/0.1.3/js/msal.min.js"></script>
<!-- The 'bluebird' and 'fetch' references below are required if you need to run this application on Internet Explorer -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.3.4/bluebird.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/2.0.3/fetch.min.js"></script>
<script type="text/javascript" src="msalconfig.js"></script>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
var msalconfig = {
clientID: "3d61bf0f-32ce-439e-8097-657c6a1e3c8e",
redirectUri: location.origin
};<!DOCTYPE html>
<html>
<head>
<!-- bootstrap reference used for styling the page -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<title>JavaScript SPA Guided Setup</title>
<meta charset="utf8" />
</head>
<body style="margin: 40px">
<button id="callGraphButton" type="button" class="btn btn-primary" onclick="callGraphApi()">Call Microsoft Graph API</button>
<div id="errorMessage" class="text-danger"></div>
<div class="hidden">
<h3>Graph API Call Response</h3>
<pre class="well" id="graphResponse"></pre>
</div>
<div class="hidden">
<h3>Access Token</h3>
<pre class="well" id="accessToken"></pre>
</div>
<div class="hidden">
<h3>ID Token Claims</h3>
<pre class="well" id="userInfo"></pre>
</div>
<button id="signOutButton" type="button" class="btn btn-primary hidden" onclick="signOut()">Sign out</button>
<!-- This app uses cdn to reference msal.js (recommended).
You can also download it from: https://github.com/AzureAD/microsoft-authentication-library-for-js -->
<script src="https://secure.aadcdn.microsoftonline-p.com/lib/0.1.3/js/msal.min.js"></script>
<!-- The 'bluebird' and 'fetch' references below are required if you need to run this application on Internet Explorer -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.3.4/bluebird.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/2.0.3/fetch.min.js"></script>
<script type="text/javascript" src="msalconfig.js"></script>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
var msalconfig = {
clientID: "your id here", // https://apps.dev.microsoft.com/?deeplink=/appList
redirectUri: location.origin
};
npm install http-server -g
http-server -p 80
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment