Vue.js 带有 vuex-oidc 的 SPA 在发布版本上有重定向循环
Vue.js SPA with vuex-oidc has redirect loops on release version
我在 Vue.js 2.5 中构建了一个单页应用程序,它还使用 IdentityServer4 + vuex-oidc 支持 OAuth2.0,并在 nginx 服务器上运行。当 运行 webpack dev server 上的应用程序时,我的设置 一切正常,但发布版本有一个重定向循环问题,我高度怀疑可能是由于 nginx 配置错误。
问题:重定向循环行为始终相同
- 用户请求导航到 /app
- oidc 插件重定向到 /connect/authorize?...
- 重定向到 /app/oidc-login(授权请求的重定向 uri)
- 重定向到 /app(回到第 2 步)
对于开发服务器,我使用配置为
的反向代理
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#example-server-configurations
配置
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>
我已经完全按照 https://github.com/perarnborg/vuex-oidc/wiki#how-to-implement-vuex-oidc 中的说明配置了 vuex-oidc,只是我将 oidcStore 模块动态添加到 vuex。
因为一切都在开发服务器上正常工作,我已经认为这是一个 nginx 问题,我不确定提供我的 code/setup 的其他部分会有帮助,但请让我知道以防万一遗漏了一些东西,我会分享更多。
谢谢
正如我之前所怀疑的,问题实际上是 nginx 部分的配置错误。基本上网络服务器正在剥离从 IdentityServer 返回的 id_token
参数(以及任何其他查询参数),这导致了重定向循环。有两种解决方案。简单的解决方案是向 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
查询类似于提议的 。
我在 Vue.js 2.5 中构建了一个单页应用程序,它还使用 IdentityServer4 + vuex-oidc 支持 OAuth2.0,并在 nginx 服务器上运行。当 运行 webpack dev server 上的应用程序时,我的设置 一切正常,但发布版本有一个重定向循环问题,我高度怀疑可能是由于 nginx 配置错误。
问题:重定向循环行为始终相同
- 用户请求导航到 /app
- oidc 插件重定向到 /connect/authorize?...
- 重定向到 /app/oidc-login(授权请求的重定向 uri)
- 重定向到 /app(回到第 2 步)
对于开发服务器,我使用配置为
的反向代理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#example-server-configurations
配置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>
我已经完全按照 https://github.com/perarnborg/vuex-oidc/wiki#how-to-implement-vuex-oidc 中的说明配置了 vuex-oidc,只是我将 oidcStore 模块动态添加到 vuex。
因为一切都在开发服务器上正常工作,我已经认为这是一个 nginx 问题,我不确定提供我的 code/setup 的其他部分会有帮助,但请让我知道以防万一遗漏了一些东西,我会分享更多。
谢谢
正如我之前所怀疑的,问题实际上是 nginx 部分的配置错误。基本上网络服务器正在剥离从 IdentityServer 返回的 id_token
参数(以及任何其他查询参数),这导致了重定向循环。有两种解决方案。简单的解决方案是向 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
查询类似于提议的