Vue.js SPA с vuex-oidc имеет циклы перенаправления в версии выпуска

У меня есть одностраничное приложение, встроенное в Vue.js 2.5, которое также поддерживает OAuth2.0 с использованием IdentityServer4 + vuex-oidc и работает на сервере nginx. Все с моей настройкой работает нормально при запуске приложения на сервере webpack, но в версии выпуска есть проблема с циклом перенаправления, которая, как я подозреваю, может быть связана с неправильной настройкой nginx.

Проблема: поведение цикла перенаправления всегда одинаково

  1. Пользователь запрашивает навигацию в / app
  2. oidc плагин перенаправляет в / подключить / авторизовать?...
  3. редирект в /app/oidc-login (URI перенаправления запроса авторизации)
  4. перенаправить в /app (вернуться к шагу 2)

Для сервера dev я использую обратный прокси, настроенный как

location /app {
    fastcgi_buffer_size 128k;
    fastcgi_buffers 4 256k;
    fastcgi_busy_buffers_size 256k;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_pass https://127.0.0.1:55100;
    proxy_temp_path C:/myapp/nginxRP;
}

Но поскольку я использую режим истории в маршрутизаторе, версия выпуска настраивается в соответствии с https://router.vuejs.org/guide/essentials/history-mode.html

fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
location /app {
    try_files $uri $uri/ /index.html;
}

Где версия выпуска приложения (index.html и статические файлы) находится в .. \ nginx \ html \ app

Вот моя конфигурация vue-router

const router = new Router({
    mode: "history",
    base: "/app/",
    routes: [
        {
            path: "/oidc-login",
            name: "oidcCallback",
            component: OidcCallback,
            meta: {
                isOidcCallback: true,
                isPublic: true
            }
        },
        {
            path: "/oidc-silent-login",
            name: "oidcSilentCallback",
            component: OidcSilentCallback,
            meta: {
                isOidcCallback: false,
                isPublic: true
            }
        },
        {
            path: "/",
            name: HOME_PAGE_TITLE,
            component: Main
        },
        {
            path: "*",
            name: "Page Not Found",
            component: NotFound
        }
    ]
});

И компоненты OidcCallback это

<template>
  <div></div>
</template>

<script>
import { mapActions } from "vuex";
import { OIDC_MODULE_NAMESPACE } from "../../store/store";

export default {
    name: "OidcCallback",
    methods: {
        ...mapActions(OIDC_MODULE_NAMESPACE, [
            "oidcSignInCallback"
        ])
    },
    mounted () {
        this.oidcSignInCallback()
            .then((redirectPath) => {
                this.$router.push(redirectPath);
            })
            .catch((err) => {
                console.error(err);
                this.$router.push("/signin-oidc-error"); // TODO
            });
    }
};
</script>

Я настроил vuex-oidc в точности так, как указано в https://github.com/perarnborg/vuex-oidc/wiki, за исключением того, что я динамически добавляю модуль oidcStore в vuex.

Так как на сервере dev все работает, и я уже думаю, что это проблема nginx, я не уверен, что другие части моего кода / настройки были бы полезны, но, пожалуйста, дайте мне знать, если я что-то упустил, и я ' поделюсь больше.

Спасибо

1 ответ

Решение

Как я и подозревал ранее, проблема была в неправильной конфигурации nginx. в основном веб-сервер раздевал id_token параметр, возвращаемый из IdentityServer (и любых других параметров запроса), что привело к циклу перенаправления. Есть два решения этого. простое решение - добавить правило перезаписи в конфигурацию nginx и заменить его чем-то вроде

location ^~ /app/ {
    if (!-f $request_filename) {
        rewrite ^/app/(.*)$ /app/index.html;
    }
}

Чтобы он правильно передавал каждый URL-запрос приложению Vue, которое затем обрабатывается Vue-Router и промежуточным программным обеспечением vuex-oidc (никаких изменений при настройке vue-router не требуется, достаточно только указанной выше конфигурации nginx). Другое решение состоит в том, чтобы использовать дизайн "Front Controller Pattern" и передать полный URI с его аргументами в SPA. Это по-прежнему требует настройки nginx немного по-другому, как

location /app {
    try_files $uri $uri/ /index.html?route=$uri&$args;
}

Больше не переписывает, но дополнительно налагает особую обработку в Vue-Router для выполнения навигации оттуда с помощью навигационной охраны, и это route запрос похож на то, что предлагается здесь.

Другие вопросы по тегам