Vue + MSAL2.x + Azure B2C 配置文件编辑

Vue + MSAL2.x + Azure B2C Profile Editing

首先,我没有找到使用 MSAL 2.x 的 Vue 特定示例,我们想使用 PKCE 流程。我在 AuthService handleResponse 之前遇到路由器防护 运行 的方式问题,所以我一定是做错了什么。

在我的 main.js 我正在做这个...

// Use the Auth services to secure the site
import AuthService from '@/services/AuthServices';
Vue.prototype.$auth = new AuthService()

然后在我的 AuthConfig.js 中,我使用此请求登录:

loginRequest : {
      scopes: [
         "openid", 
         "profile", 
         process.env.VUE_APP_B2C_APISCOPE_READ, 
         process.env.VUE_APP_B2C_APISCOPE_WRITE
      ]
   },

文档说它应该重定向到请求页面,但这并没有发生。如果用户转到受保护的主页,他们将被重定向到登录。他们登录,所有内容都正确存储,因此他们实际上 登录,但随后他们被发送回站点的根重定向 URL,而不是主页。

当用户想要登录时,我们只是将他们发送到受保护的主页,并且在路由器守卫中调用了一个登录方法,如下所示:

router.beforeEach(async (to, from, next) => {
   const requiresAuth = to.matched.some(record => record.meta.requiresAuth)
   const IsAuthenticated = await Vue.prototype.$auth.isAuthenticated()
   console.log(`Page changing from ${from.name} to ${to.name}, requiresAuth = ${requiresAuth}, IsAuthenticated = ${IsAuthenticated}`)
   if (requiresAuth && !IsAuthenticated) 
   {
     next(false)
     console.log('STARTING LOGIN')
     Vue.prototype.$auth.login()
     // Tried this
     // Vue.prototype.$auth.login(to.path)
   } else {
     next()
   }
 })

AuthServices.js我有这个...

   // The user wants to log in
   async login(nextPg) {

      // Tell B2C what app they want access to and their invitation ID if they are new
      if (store.getters.userEmail != null) {
         aCfg.loginRequest.loginHint = store.getters.userEmail
      }

      aCfg.loginRequest.state = "APP=" + store.getters.appCode
      if (store.getters.appointmentLink != null && store.getters.appointmentLink != '') {
         aCfg.loginRequest.state += ",ID=" + store.getters.appointmentLink
      }

      // Tried this
      // if (nextPg && nextPg != '') {
      //    aCfg.loginRequest.redirectUrl = process.env.VUE_APP_B2C_REDIRECT_URL + nextPg
      // }

      return await this.msalInst.loginRedirect(aCfg.loginRequest)
   }

我尝试在登录方法中放置一个 nextPg 参数,并在登录请求中添加一个 redirectUrl 属性,但这给了我一个错误,说它不是已配置的重定向 URL 之一。

另外,我正在努力使使用上述技术时的用户体验更好。当您查看 MSAL2.x SPA 示例时,我看到当从配置文件编辑返回时,用户已注销,他们需要重新登录。对我来说,这听起来像是糟糕的用户体验。此处示例:https://github.com/Azure-Samples/ms-identity-b2c-javascript-spa/blob/main/App/authRedirect.js

我是否需要只创建自己的个人资料编辑页面并使用 MSGraph 保存数据来防止这种情况发生?对不起,菜鸟问题。想法?

Update - 我的解决方法似乎很俗气,是将这两种方法添加到我的 AuthService.js:

   storeCurrentRoute(nextPath) {
      if (!nextPath) {
         localStorage[STOR_NEXT_PAGE] = router.history.current.path
      } else {
         localStorage[STOR_NEXT_PAGE] = nextPath
      }
      console.log('Storing Route:', localStorage[STOR_NEXT_PAGE])
   }

   reEstablishRoute() {
      let pth = localStorage[STOR_NEXT_PAGE]
      if (!!pth && router.history.current.path != pth) {
         localStorage[STOR_NEXT_PAGE] = ''
         console.log(`Current path is ${router.history.current.path} and reEstablishing route to ${pth}`)
         router.push({ path: pth })
      }
   }

我首先在登录方法中调用 storeCurrentRoute(),然后在 handleResponse() 中,当它未从 profileEdit 或密码更改返回时,我调用 reEstablishRoute()。看来我应该能够在没有这个的情况下工作。

第二个更新 - 从 B2C 的 ProfileEdit 用户流程返回时,MSAL 组件未正确注销我。这是我的 AuthService handlePolicyChange() 方法中的代码:

} else if (response.idTokenClaims[clmPolicy] === aCfg.b2cPolicies.names.editProfile) {
         Vue.nextTick(() => {
            console.log('BACK FROM Profile Change')
            Vue.prototype.$swal(
               "Success!",
               "Your profile has been updated.<br />Please log in again.",
               "success"
            ).then(async () => {
               this.logout()
            })
          })

      } 
:
   // The user wants to log out (all accounts)
   async logout() {
      // Removes all sessions, need to call AAD endpoint to do full logout
      store.commit('updateUserClaims', null)
      store.commit('updateUserEmail', null)

      let accts = await this.msalInst.getAllAccounts()
      for(let i=0; i<accts.length; i++) {
         const logoutRequest = {
            account: accts[i],
            postLogoutRedirectUri: process.env.VUE_APP_B2C_REDIRECT_URL
         };
         await this.msalInst.logout(logoutRequest);
      }
      return
   }

它工作正常,直到调用 logout() 运行s 没有错误,但我查看了我的站点存储(在 Chrome 的调试 window > 应用程序中)并且看起来 MSAL 没有像我正常注销时那样清除其条目(总是成功)。想法?

作为 MSAL 身份验证请求的一部分,发送 state 参数。 Base64 编码用户在此参数中离开的位置。 MSAL 公开了 extraQueryParameters,您可以在其中放入一个字典对象并发送身份验证请求,将您的 state 键值对放入 extraQueryParameters.

state参数将在回调响应中返回,用它来将用户发送到您需要的地方。