使用MSAL v0.1.3和Aurelia进行身份验证

时间:2018-01-17 20:24:23

标签: aurelia msal

我找到了所有使用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试图处理导航等的方式有关,但我无法弄清楚事情出在哪里。

非常感谢任何帮助!

1 个答案:

答案 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()生命周期回调。