Использование MSAL v0.1.3 с Aurelia для аутентификации

Я нашел все виды примеров использования 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>

Этот код прекрасно работает. Вы нажимаете кнопку "Вход", отображается всплывающее окно "Вход", вы выбираете пользователя, вводите свой пароль, и всплывающее окно исчезает, а пользовательский интерфейс обновляется соответствующим образом с использованием имени пользователя и токена.

Теперь я пытаюсь добавить это в мое приложение 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"))
         });
   }  
}

Однако с этим кодом приложение загружается и переходит на страницу входа, которая выскакивает во всплывающем окне входа. Однако, как только пользователь вводит / выбирает имя и пароль, всплывающее окно не исчезает. Приложение (позади всплывающего окна), кажется, перезагружается и перемещается к view.dels app.js, но всплывающее окно остается на экране и, кажется, просит пользователя ввести / выбрать имя пользователя.

Я также попытался использовать loginRedirect, а не loginPopup, с тем же результатом, что приложение постоянно перенаправляется на страницу входа даже после аутентификации.

Я предполагаю, что это связано с тем, как MSAL пытается реагировать на приложение, и с тем, как Aurelia пытается управлять навигацией и т. Д., Но я не могу понять, где все идет не так, как надо.

Любая помощь будет принята с благодарностью!

1 ответ

Решение

Использовать attached() обратный вызов жизненного цикла

Кажется, все работает, но всплывающее окно не исчезает. Трудно понять почему, не видя код в действии, но первое, что вы захотите попробовать, - это перенести соответствующий код в attached() обратный вызов, который вызывается, когда представление и модель представления связаны и добавляются в DOM.

НЕ возвращать обещание входа в activate()

Если вы вернули обещание входа в activate()Активация не будет завершена, пока не будет выполнено обещание. Тем не мение, 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() жизненный цикл обратного вызова.

Другие вопросы по тегам