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
参数将在回调响应中返回,用它来将用户发送到您需要的地方。
首先,我没有找到使用 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
参数将在回调响应中返回,用它来将用户发送到您需要的地方。