Клиент Auth0 пуст в Vue SPA при обновлении страницы - PullRequest
2 голосов
/ 19 февраля 2020

У меня есть Vue SPA на основе одного из приложений быстрого запуска Auth0 (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
});

Это на самом деле работает нормально, если приложение перезагружается с моего сервера npm dev, оно обращается к моему 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, смонтированные и т. Д. c), все с тем же результатом. Клиент становится доступным через 800 мс или около того, но не при выполнении этого кода.

Это явно проблема синхронизации, но мне не ясно, как заставить мой компонентный код сидеть и подождите, пока this.auth0Client не станет нулевым, не сделав ничего ужасного и хакерского, как setInterval.

1 Ответ

0 голосов
/ 20 февраля 2020

Я нашел обходной путь, который я добавлю в качестве ответа на случай, если у кого-то еще возникнет эта проблема, хотя на самом деле это не тот ответ, который я хочу. Согласно 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
        });
    }
}

Это вряд ли идеально, но это работает.

...