Vue 3.0 Classic Flow Okta Widget Error - "Interaction Code Flow isn't enabled"

I am migrating a working Vue2 to a Vue3 app, and from widget 4.x to 7.x, using the classic flow for sign-in.

I am getting an error saying that Interaction Code Flow isn’t enabled. However, I’m specifically trying to use the Classic Flow by setting the environment variables (useInteractionCodeFlow: false, useClassicEngine: true) when initializing the okta object in okta/index.js.

I reached out to the help desk and they responded that since I was using a free dev account, they could not “link my account to a Paid Okta Org” and could not help me. Hoping someone here can un f**k what I’ve done in my migration attempt. I will admit I have gotten bogged down in Okta’s multiple examples of creating a vue app and all the login-methods that are out there, especially given the Vue2 to Vue3 upgrades (and I’m not using Vue-CLI, but VITE).
Thanks in advance.

Here are the relevant parts of the relevant files
index.html,
okta/index.js,
main.js
router/index.js
Login.vue

INDEX.HTML:

  <!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="./favicon.ico">
    ...
    <title>xxx</title>
  </head>
  <body>
    <noscript>
      <strong>xxx</strong>
    </noscript>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>

      <!-- Latest OKTA -->
    <script src="https://global.oktacdn.com/okta-signin-widget/7.2.2/js/okta-sign-in.min.js" type="text/javascript"></script>
    <link href="https://global.oktacdn.com/okta-signin-widget/7.7.2/css/okta-sign-in.min.css" type="text/css" rel="stylesheet"/>
...
  </body>
</html>

OKTA/INDEX.JS

import OktaSignIn from '@okta/okta-signin-widget'
import { OktaAuth } from '@okta/okta-auth-js'

const BASEURL = 'https://dev-123456.okta.com'
const ISSUER = import.meta.env.VITE_APP_ISSUER || "https://dev-123456.okta.com/oauth2/default";
const SPA_CLIENT_ID = import.meta.env.VITE_APP_SPA_CLIENT_ID || "blablabla";
const CALLBACK_PATH = import.meta.env.VITE_APP_CALLBACK_PATH || window.location.origin + '/login/callback';
const SCOPES = ['openid', 'profile', 'email'];
const OKTA_TESTING_DISABLEHTTPSCHECK = import.meta.env.VITE_APP_OKTA_TESTING_DISABLEHTTPSCHECK || false;


const oktaSignIn = new OktaSignIn({
  baseUrl: BASEURL,
  clientId: SPA_CLIENT_ID,
  redirectUri: 'http://localhost:5173/login/callback',
  authParams: {
    pkce: true,
    issuer: ISSUER,
    display: 'page',
    scopes: SCOPES,
    useInteractionCodeFlow: false, // Set to false if your app is still using the Implicit flow
    useClassicEngine: true, // Set to true to use the Classic Sign In Widget on your custom login page
    testing: {
        disableHttpsCheck: OKTA_TESTING_DISABLEHTTPSCHECK
        }
    }
});

const oktaAuth = new OktaAuth({
  issuer: ISSUER,
  clientId: SPA_CLIENT_ID,
  redirectUri: window.location.origin + '/login/callback',
  scopes: ['openid', 'profile', 'email'],
})

export { oktaAuth, oktaSignIn };

MAIN.JS

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import OktaVue from '@okta/okta-vue'

import { oktaAuth } from './okta';

const app = createApp(App)
    .use(router)
    .use(OktaVue, { 
        oktaAuth,
        onAuthRequired: () => {
            router.push('/login')
         },
         onAuthResume: () => {
            router.push('/login')
          }
        })
    //Added to make v-focus directive work on vue templates
    .directive( 'focus', {
        // When the bound element is inserted into the DOM...
        mounted: function (el) {
            // Focus the element
            el.focus()
        } 
    })
    .mount('#app');

ROUTER/INDEX.JS

import { createRouter, createWebHistory } from 'vue-router'

import { LoginCallback, navigationGuard } from '@okta/okta-vue'

import Login from '@/components/Login.vue'
...

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'login',
      component: Login,
    },
    {
      path: '/login',
      component: Login ,
    },
  
    {
      // 2023.05.26 New Callback route for Okta
      path: '/login/callback',
      component: LoginCallback
    },
    {
      path: '/logout',
      beforeEnter (to, from, next) {
        Auth.logout();
        next('/');
      }
    },
    {
      path: '/logout',
      beforeEnter (to, from, next) {
        Auth.logout();
        next('/');
      }
    },
... other routes here
  ]
})
// Due to navigation guards mixin issue in vue-router-next, navigation guard logic need to be added manually
router.beforeEach(navigationGuard)

export default router

LOGIN.VUE

<template>
  <div class="login">
    <div id="okta-signin-container"></div>
  </div>
</template>

<script>
import {oktaSignIn} from '../okta'

export default {
  name: 'Login',
  mounted: function () {
    this.$nextTick(function () {
      oktaSignIn.showSignInAndRedirect(
        { el: '#okta-signin-container' }
      )
    })
  },
  unmounted () {
    // Remove the widget from the DOM on path change
    oktaSignIn.remove()
  }
}
</script>

Can you try moving useClassicEngine (you shouldn’t need to set useInteractionCodeFlow in Widget v7) out of authParams and set it within the OktaSignIn config directly? E.g

const oktaSignIn = new OktaSignIn({
  baseUrl: BASEURL,
  clientId: SPA_CLIENT_ID,
  redirectUri: 'http://localhost:5173/login/callback',
  useClassicEngine: true, // Set to true to use the Classic Sign In Widget on your custom login page
  authParams: {
    pkce: true,
    issuer: ISSUER,
    display: 'page',
    scopes: SCOPES,
    testing: {
        disableHttpsCheck: OKTA_TESTING_DISABLEHTTPSCHECK
        }
    }
});

Wow. Just wow. I feel so stupid. But, that’s why we ask for help!!!

Thanks Andrea!

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.