我找到了所有使用MSAL的例子,甚至使用MSAL和SPA应用程序(通常是Angular或React)的例子,但我很难与Aurelia合作。
我执行了以下操作以确保库实际上按预期工作。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://secure.aadcdn.microsoftonline-p.com/lib/0.1.3/js/msal.min.js"></script>
<style>
.hidden {
visibility: hidden;
}
</style>
</head>
<body>
<div id="username"></div>
<div id="token"></div>
<button id="login" onclick="loginPopup()">Log In</button>
<button id="logout" class="hidden">Log Out</button>
<script>
var authClient = new Msal.UserAgentApplication("my v2 endpoint client id",null);
function loginPopup(){
authClient.loginPopup(["openid","user.readbasic.all"])
.then(token => {
authClient.acquireTokenSilent(["user.readbasic.all"])
.then(accessToken => {
updateUI(token);
},
error => {
authClient.acquireTokenPopup(["user.readbasic.all"])
.then(accessToken => {
updateUI(token);
},
error => {
console.log("Token Error: " + error)
})
})
},
error =>{
console.log("Login error " + error)
})
}
function updateUI(token){
var loginbutton = document.getElementById("login");
loginbutton.className = "hidden";
let usernamediv = document.getElementById("username");
let tokendiv = document.getElementById("token");
usernamediv.innerText = authClient.getUser().name;
tokendiv.innerText = token;
}
</script>
</body>
</html>
该代码效果很好。单击“登录”按钮,显示“登录弹出窗口”,选择用户,输入密码,弹出窗口消失,用户名和令牌正确更新UI。
现在我尝试将此添加到我的Aurelia应用程序中,如下所示:
main.js
export async function configure(aurelia){
aurelia.use
.standardConfiguration()
.developmentLogging();
let msClient = new Msal.UserAgentApplication('my v2 endpoint client id",null);
aurelia.use.instance("AuthService",msClient);
await aurelia.start();
if(msClient.getUser()) {
await aurelia.setRoot(PLATFORM.moduleName("app"));
else
await aurelia.setRoot(PLATFORM.moduleName("login/login"));
login.js
export class Login {
static inject = [Aurelia, "AuthService"]
constructor(aurelia, auth){
this.authService = auth
this.app = aurelia
}
activate(){
//Also tried this code in constructor
this.authService.loginPopup(["openid","user.readbasic.all"])
.then(token => {
this.app.setRoot(PLATFORM.moduleName("app"))
});
}
}
但是,使用此代码,应用程序会加载并导航到弹出登录弹出窗口的登录页面。但是,一旦用户输入/选择名称和密码,弹出屏幕就不会消失。应用程序(弹出窗口后面)似乎重新加载并导航到app.js视图模型,但弹出窗口仍保留在屏幕上,似乎要求用户输入/选择用户名。
我也尝试过使用loginRedirect而不是loginPopup,结果类似,即使在验证后应用程序也会不断重定向到登录页面。
我猜这与MSAL试图回应应用程序的方式以及Aurelia试图处理导航等的方式有关,但我无法弄清楚事情出在哪里。
非常感谢任何帮助!
答案 0 :(得分:0)
attached()
生命周期回调似乎一切正常,但弹出窗口并没有消失。很难知道为什么没有看到代码在运行,但是你想要尝试的第一件事是将相关代码移动到attached()
回调,一旦视图和视图模型被绑定并添加就会调用到DOM。
activate()
如果您在activate()
中返回了登录承诺,则在承诺解决之前,激活将无法完成。但是,当promise也解析时,将调用app.setRoot()
,这意味着您将在第一个导航完成之前开始新的导航。这很糟糕。
activate() {
// THIS WOULD BREAK
return this.authService.loginPopup(["openid","user.readbasic.all"])
.then(token => {
this.app.setRoot(PLATFORM.moduleName("app"))
});
}
detatched()
生命周期回调如果这不起作用,接下来要做的是检查authService.loginPopup()
是否正确登录并解析。如果是这样,您可以随时手动删除DOM中的弹出窗口,如果库本身没有清理的话。您应该执行此detatched()
生命周期回调。