页面刷新时,Vue SPA中的Auth0客户端为空

时间:2020-02-19 14:48:29

标签: javascript vue.js authentication single-page-application auth0

我有一个基于Auth0快速入门应用程序(https://github.com/auth0-samples/auth0-vue-samples)的Vue SPA。开箱即用,一切正常,但是,一旦我尝试在组件代码中使用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
});

如果该应用程序从我的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)

在authWrapper.js文件(Auth0客户端所在的文件)中,函数调用在此处:

getTokenSilently(o) {
    return this.auth0Client.getTokenSilently(o);
}

当我调试呼叫时,“ auth0Client”不存在,这就是失败的原因。我无法理解的是在尝试拨打电话之前确保它确实存在的正确方法。样本中没有任何内容指示执行此操作的正确方法。我尝试将组件代码放入不同的组件和不同的Vue生命周期挂钩(已创建,beforeMount,已安装等)中,所有结果均相同。客户端将在大约800毫秒后变得可用,但在执行此代码后不可用。

这显然是一个时序问题,但是我不清楚如何告诉我的组件代码坐下来等到this.auth0Client为非null而不进行诸如setInterval之类的可怕和棘手的事情。

1 个答案:

答案 0 :(得分:2)

我现在想出了一种解决方法,以防万一其他人遇到这个问题时我将其添加为答案,尽管这并不是我真正想要的答案。对于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
        });
    }
}

这并不理想,但是确实可以。