Reputation: 1662
I have a single page application built in Vue.js 2.5 which also has OAuth2.0 support using IdentityServer4 + vuex-oidc and runs on an nginx server. Everything with my setup works fine when running the app on webpack dev server, but the release version has a redirect loop problem which I highly suspect might be due to nginx misconfiguration.
Problem: The redirect loop behavior is always the same
For the dev server I am using a reverse proxy configured as
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;
}
But since I'm using history mode in router, the release version is configured as per 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;
}
Where the release version of the app (index.html and static files) are located at ..\nginx\html\app
Here's my vue-router configuration
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
}
]
});
And the OidcCallback components is
<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>
I've configured vuex-oidc pretty much exactly as instructed in https://github.com/perarnborg/vuex-oidc/wiki#how-to-implement-vuex-oidc except that I dynamically add the oidcStore module to vuex.
Since everything just works in the dev server and I already think this is an nginx issue, I'm not sure providing what other parts of my code/setup would be helpful but please let me know in case I'm missing something and I'll share more.
Thanks
Upvotes: 2
Views: 1953
Reputation: 1662
As I suspected earlier, the problem was in fact a misconfiguration on the nginx part. basically the webserver was stripping the id_token
parameter returned from IdentityServer (and any other query parameters) which resulted in the redirect loop. There are two solution to this. the easy solution is to add a rewrite rule to nginx configuration and basically replace it with something like
location ^~ /app/ {
if (!-f $request_filename) {
rewrite ^/app/(.*)$ /app/index.html;
}
}
So that it correctly passes every url query to the Vue app which is then handled by Vue-Router and the vuex-oidc middleware (no changes required in setting up vue-router, only the above nginx configuration is enough). Another solution is to use a "Front Controller Pattern" design and pass the complete uri with its arguments to the SPA. This still requires configuring nginx a bit differently like
location /app {
try_files $uri $uri/ /index.html?route=$uri&$args;
}
No more rewrites, but additionally imposes special treatment in Vue-Router to perform navigation from there using a navigation guard and this route
query similar to what is proposed here.
Upvotes: 1