okta / okta-vue

OIDC SDK for Vue
https://github.com/okta/okta-vue
Other
46 stars 26 forks source link

Allow non-history-mode Vue router mode (requires hash in redirect URL). #26

Open mfickett opened 4 years ago

mfickett commented 4 years ago

I'm submitting a:

Current behavior

With the router in default (hash) mode, there are two issues: Redirecting to a full path (localhost:8080/login/callback) routes to my root component instead of my callback; and setting the callback path to the component hash (localhost:8080/#/login/callback) is not allowed in the web console (it says "The redirect URIs must not contain a fragment identifier.").

If I change to mode: "history" in my router, then it works, but requires slightly more complicated serving configuration.

Expected behavior

Using hash mode in the Vue router works with Okta.

Also, it may be a benefit for setup documentation to specifically call out the history v. hash mode requirements for the router: https://developer.okta.com/docs/guides/sign-into-spa/vue/define-callback/ . They do use history mode but don't highlight that it's required.

Minimal reproduction of the problem with instructions

import Vue from "vue";
import VueRouter, { RouteConfig } from "vue-router";

import Auth from "@okta/okta-vue";

import { oktaConfig, LOGIN_CALLBACK_PATH } from "@/oktaconfig";
import Home from "@/views/Home.vue";

Vue.use(VueRouter);
Vue.use(Auth, { ...oktaConfig });

const routes: Array<RouteConfig> = [
  {
    path: LOGIN_CALLBACK_PATH,
    name: "logincallback",
    component: Auth.handleCallback()
  },
  {
    path: "/",
    name: "home",
    component: Home
  }
];

const router = new VueRouter({
  // Without history mode, it does not work.
  //mode: "history",
  routes
});

// Require Okta auth for all paths.
router.beforeEach(async (to, from, next) => {
  const oktaAuth = Vue.prototype.$auth;
  if (to.path == LOGIN_CALLBACK_PATH) {
    next();
  } else if (!await oktaAuth.isAuthenticated()) {
    oktaAuth.login(to.path);
  } else {
    next();
  }
});

Extra information about the use case/user story you are trying to implement

I'd like to serve my SPA without having associated server-side redirects (for history mode).

Environment

swiftone commented 4 years ago

@mfickett - Thanks for the report.

As you've noted, hash fragments present a real complication - Per the OIDC spec, fragments are not allowed in redirects, so your logout callback cannot be a hash fragment. But without a hash fragment, hash-based routing has problems - redirecting to a callback to handle tokens in the URL doesn't work if the code has no way to know if it should process tokens in the url.

This problem is not unique to vue, though every front end SDK handles routing a little differently.

We have an existing task where we're trying to resolve this issue, I'll make sure this issue gets attached to it.

swiftone commented 4 years ago

Internal ref: OKTA-320773

mfickett commented 4 years ago

Thanks for the quick reply. I didn't realize this was part of the OpenID spec. Then history mode it is, though I'll be interested to hear if you develop a way around it.