Created
July 25, 2019 11:21
-
-
Save pdib/5dab0f8fa1fed1bc676b97c2ddc38f4b to your computer and use it in GitHub Desktop.
Use adal-angular to login and call APIs with Microsoft authentication
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useState } from "react"; | |
import AuthenticationContext from "adal-angular"; | |
import "./App.css"; | |
// Use the AppId and redirectUri you get after registering your App in the Azure Portal. | |
// https://docs.microsoft.com/en-us/graph/auth-register-app-v2 | |
const authContext = new AuthenticationContext({ | |
clientId: "<AppId-from-azure-portal>", | |
popUp: false, | |
redirectUri: "http://localhost:8000", | |
postLogoutRedirectUri: "http://localhost:8000", | |
}); | |
function useUser() { | |
authContext.handleWindowCallback(); | |
const user = authContext.getCachedUser(); | |
const [loggedIn, setLoggedIn] = useState(!!user); | |
function loginCallback(errorDesc: string | null, token: string | null, error: any) { | |
if (token && !error) { | |
setLoggedIn(true); | |
} | |
} | |
function login() { | |
authContext.callback = loginCallback; | |
authContext.login(); | |
} | |
return { | |
loggedIn, | |
login, | |
logout: () => { | |
authContext.logOut(); | |
} | |
}; | |
} | |
function acquireTokenAsync(resource: string): Promise<string> { | |
return new Promise((resolve, reject) => { | |
function cb(errorDesc: string | null, token: string | null, error: any) { | |
if (!error && token) { | |
resolve(token); | |
} else { | |
if (error === "interaction_required") { | |
if (authContext.popUp) { | |
authContext.acquireTokenPopup(resource, null, null, cb); | |
} else { | |
authContext.acquireTokenRedirect(resource, null, null); | |
} | |
} else { | |
reject(error); | |
} | |
} | |
} | |
authContext.acquireToken("https://graph.microsoft.com", cb); | |
}); | |
} | |
function useGraphInfo() { | |
const [userName, setUserName] = useState(""); | |
async function loadUserName() { | |
try { | |
const token = await acquireTokenAsync("https://graph.microsoft.com"); | |
const response = await fetch("https://graph.microsoft.com/v1.0/me/", { | |
headers: { Authorization: `Bearer ${token}` } | |
}); | |
const reader = response.body!.getReader(); | |
reader | |
.read() | |
.then(readResult => new TextDecoder("utf-8").decode(readResult.value)) | |
.then(JSON.parse) | |
.then(json => { | |
setUserName(json.displayName); | |
}); | |
} catch (e) { | |
console.log("error", e); | |
} | |
} | |
return { | |
userName, | |
loadUserName | |
}; | |
} | |
const App: React.FC = () => { | |
const loginInfo = useUser(); | |
const graphInfo = useGraphInfo(); | |
return ( | |
<div className="App"> | |
<header className="App-header"> | |
{loginInfo.loggedIn && ( | |
<> | |
<span>You're logged in</span> | |
<button onClick={loginInfo.logout}>Logout</button> | |
<button onClick={graphInfo.loadUserName}>Load user name</button> | |
<span>{graphInfo.userName}</span> | |
</> | |
)} | |
{!loginInfo.loggedIn && <button onClick={loginInfo.login}>Login</button>} | |
</header> | |
</div> | |
); | |
}; | |
export default App; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment