ada*_*tlx 5 javascript authentication single-page-application vue.js auth0
我有一个基于 Auth0 的快速入门应用程序之一的 Vue SPA(https://github.com/auth0-samples/auth0-vue-samples)。开箱即用,一切正常,但是一旦我尝试在组件代码中使用 Auth0 客户端,我就会遇到问题。我遵循了“调用 API”教程(https://auth0.com/docs/quickstart/spa/vuejs/02-calling-an-api),它无助地只展示了如何使用按钮调用 API。我想要做的是在初始页面加载时触发对我的 API 的经过身份验证的调用,以便我可以确保某些数据存在于我自己的 API 中(如果没有,则创建它)。这看起来应该很简单。我只是将这段代码扔到我创建的 Vue 组件钩子中:
await this.$auth.getTokenSilently().then((authToken) => {
// reach out to my API using authToken
});
Run Code Online (Sandbox Code Playgroud)
如果应用程序从我的 npm 开发服务器热重新加载,这实际上可以正常工作,它会访问我的 API,该 API 使用令牌授权请求,并发回正确的数据。问题是当我手动重新加载页面时,这会导致:
Uncaught (in promise) TypeError: Cannot read property 'getTokenSilently' of null
at Vue.getTokenSilently (authWrapper.js?de49:65)
at _callee$ (App.vue?234e:49)
Run Code Online (Sandbox Code Playgroud)
在 authWrapper.js 文件(Auth0 客户端所在的位置)中,函数调用如下:
getTokenSilently(o) {
return this.auth0Client.getTokenSilently(o);
}
Run Code Online (Sandbox Code Playgroud)
当我调试调用时,“auth0Client”不存在,这就是它失败的原因。我无法理解的是在我尝试拨打电话之前确保它确实存在的正确方法。样本中没有任何内容表明执行此操作的正确方法。我尝试将我的组件代码放在不同的组件和不同的 Vue 生命周期钩子(created、beforeMount、mounted 等)中,所有结果都相同。客户端成为后800毫秒左右可用,但不是这个代码执行时。
这显然是一个时间问题,但我不清楚如何告诉我的组件代码坐下来等待 this.auth0Client 为非空而不做一些像 setInterval 那样可怕和骇人听闻的事情。
我现在找到了一个解决方法,我会将其添加为答案,以防其他人遇到此问题,尽管这并不是我真正想要的答案。根据 authGuard,您可以使用从 authWrapper 导出的“实例”,并在执行取决于 auth0Client 准备就绪的代码之前观察其“正在加载”标志,如下所示:
import { getInstance } from "./auth/authWrapper";
// ... Vue component:
created() {
this.init(this.doSomethingWithAuth0Client);
},
methods: {
init(fn) {
// have to do this nonsense to make sure auth0Client is ready
var instance = getInstance();
instance.$watch("loading", loading => {
if (loading === false) {
fn(instance);
}
});
},
async doSomethingWithAuth0Client(instance) {
await instance.getTokenSilently().then((authToken) => {
// do authorized API calls with auth0 authToken here
});
}
}
Run Code Online (Sandbox Code Playgroud)
这不太理想,但确实有效。