okta / okta-vue

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

Access Token is not generating with Vite + Vue3 + OKta Vue after the build in Dev Environment #142

Open PavankalyanPayyavula opened 5 months ago

PavankalyanPayyavula commented 5 months ago

Describe the bug

Hi,

I am working on developing an new application using Vue3 + Vite + Okta Vue and Codebuild.

After configuring everything. When I am running npm start I am able to open application in my local machine - Okta is generating Access Token. But the problem is when I am deploy the app in dev codebuild then It is not generating Access Token.

Even In the local storage access token is getting stored. Attaching respective screenshots for better understanding. Screenshot 2024-03-18 at 9 43 45 AM

In the network tab, Auth url is redirecting in a loop continues. Here is screenshot. Screenshot 2024-03-18 at 11 22 19 AM

I tried to console the Auth response. Here is the screenshot of it. You can see the version as well. Screenshot 2024-03-18 at 9 47 46 AM

And here is the configuration I did in my code.

vite.config.js file code -----> `import vue from "@vitejs/plugin-vue"; import path from "path"; import { defineConfig, loadEnv } from "vite"; import basicSsl from "@vitejs/plugin-basic-ssl";

export default ({ command, mode }) => { // Log command and mode for debugging if needed console.log("Command", command, mode);

// Load environment variables based on build mode const env = loadEnv(mode, process.cwd()); const isLocal = command === "serve";

return defineConfig({ plugins: [vue(), basicSsl()], define: { "process.env.NODE_ENV": JSON.stringify(isLocal ? "localServe" : env), // Set NODE_ENV to "production" for production builds explicitly "process.env": env, }, resolve: { alias: { "@": path.resolve(dirname, "./src"), }, }, css: { preprocessorOptions: { scss: { additionalData: @import "@/styles/global.scss";, }, }, }, server: { port: 8081, https: true, }, build: { outDir: "dist", // Output directory for both JS and assets assetsDir: "assets", // Separate directory for assets within dist sourcemap: false, // Disable source maps in production minify: true, // Enable minification in production emptyOutDir: true, // Consider using multiple entry points if needed rollupOptions: { // input: path.resolve(dirname, "./src/main.js"), // Single entry point (example) // Add more entry points as needed output: { entryFileNames: "[name].js", chunkFileNames: "[name].js", assetFileNames: "[name].[ext]" } }, }, }); }; main.js file code ----> import { createApp } from "vue"; import { createPinia } from "pinia"; import '@okta/okta-auth-js/polyfill'; import { OktaAuth } from "@okta/okta-auth-js"; import OktaVue from "@okta/okta-vue"; import App from "./App.vue"; import router from "./router"; import axios from "axios"; import { createVuestic } from "vuestic-ui"; import "vuestic-ui/css"; import "material-design-icons-iconfont/dist/material-design-icons.min.css"; import CONFIG from "./config"; import VueDatePicker from "@vuepic/vue-datepicker"; import "@vuepic/vue-datepicker/dist/main.css";

export const oktaAuth = new OktaAuth({ clientId: CONFIG.OKTA.CLIENT_ID, issuer: CONFIG.OKTA.ISSUER, redirectUri: CONFIG.OKTA.REDIRECT_URI, postLogoutRedirectUri: CONFIG.OKTA.POST_LOGOUT_REDIRECT_URI, scopes: ["openid", "profile", "email"], pkce: true, });

console.log("oktaAuth ", oktaAuth);

const pinia = createPinia(); const app = createApp(App); app.config.productionTip = false; axios.defaults.withCredentials = true;

app.component("VueDatePicker", VueDatePicker); app.use( createVuestic({ config: { colors: { variables: { primary: "#bf0000", }, }, }, }) );

app.use(OktaVue, { oktaAuth }); app.use(router); app.use(pinia); app.mount("#app"); App.vue file code ----->

`

Reproduction Steps?

I hope the above information helps for understand. So, I am not able to provide steps to reproduce this issue. I am wondering my it is not able to generate the access token in a different env.

SDK Versions

{ "name": "client-ui", "version": "2.0.0", "private": true, "main": "main.js", "scripts": { "start": "vite --mode localServe", "build-local": "vite build --mode localServe", "build-development": "vite build --mode development", "build-staging": "vite build --mode staging", "build-production": "vite build --mode production", "watch": "vite build --watch --mode development", "preview": "vite preview", "test:unit": "vitest", "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore", "format": "prettier --write src/" }, "dependencies": { "@okta/okta-auth-js": "^6.5.2", "@okta/okta-vue": "^5.2.0", "@vuepic/vue-datepicker": "^6.0.3", "axios": "^1.6.2", "chart.js": "^4.4.0", "moment": "^2.29.4", "papaparse": "^5.4.1", "pinia": "^2.1.6", "save": "^2.9.0", "vue": "3.4.21", "vue-chartjs": "^5.2.0", "vue-router": "^4.3.0", "vuestic-ui": "1.8.0" }, "devDependencies": { "@rushstack/eslint-patch": "^1.2.0", "@vitejs/plugin-basic-ssl": "^1.0.1", "@vitejs/plugin-vue": "^4.2.3", "@vue/eslint-config-prettier": "^7.1.0", "@vue/test-utils": "^2.3.2", "eslint": "^8.39.0", "eslint-plugin-vue": "^9.11.0", "jsdom": "^22.0.0", "material-design-icons-iconfont": "^6.7.0", "prettier": "^2.8.8", "sass": "^1.64.0", "vite": "^5.1.6", "vitest": "^1.3.1" } }

I am using node 20.9.0 version.

Additional Information

No response

jaredperreault-okta commented 5 months ago

Where in your application are you mounting your LoginCallback component? https://github.com/okta/okta-vue?tab=readme-ov-file#use-the-logincallback-component. I don't see it mounted in the code snippet

PavankalyanPayyavula commented 5 months ago

Hi @jaredperreault-okta, Thank you for the quick response. I am using LoginCallback component in the router page.

Here is my router page details.

`import { createRouter, createWebHistory } from "vue-router"; import { oktaAuth } from "../main"; import { LoginCallback, navigationGuard } from "@okta/okta-vue"; import { useLoggedInUserStore } from "../stores/modules/loggedInUser";

const router = createRouter({ history: createWebHistory(), routes: [ { path: "/sso/auth", component: LoginCallback, }, { path: "/", name: "Dashboard", meta: { requiresAuth: true }, component: () => import("../components/Pages/dashboard.vue"), beforeEnter: async (to, from, next) => { const loggedInUser = useLoggedInUserStore(); if (from.path === "/sso/auth" && (await oktaAuth.isAuthenticated())) { const user = await oktaAuth.token.getUserInfo(); let emailId = user.email; await loggedInUser.updateUserLoginTime(emailId); } next(); }, }, { path: "/kpi", name: "KPI", meta: { title: "KPI - Client", requiresAuth: true }, component: () => import("../components/Pages/kpi.vue"), beforeEnter: async (to, from, next) => { const loggedInUser = useLoggedInUserStore(); if (from.path === "/sso/auth" && (await oktaAuth.isAuthenticated())) { const user = await oktaAuth.token.getUserInfo(); let emailId = user.email; await loggedInUser.updateUserLoginTime(emailId); } next(); }, }, { path: "/userManagement", name: "User Management", meta: { title: "User Management - Client", requiresAuth: true }, component: () => import("../components/Pages/userManagement.vue"), }, { path: "/login", name: "Login", meta: { title: "Login - Client", requiresAuth: false }, component: () => import("../components/Pages/login.vue"), }, { path: "/error", name: "Error", meta: { title: "Error - Client", requiresAuth: false }, component: () => import("../components/Pages/error.vue"), }, { path: "/:catchAll(.*)", name: "404", meta: { title: "404 Not found - Client", requiresAuth: false }, component: () => import("../components/Pages/error.vue"), props: { isNotFound: false }, }, ], });

router.beforeEach(navigationGuard); router.afterEach((to) => { document.title = to.meta.title || "Client"; });

export default router; `

jaredperreault-okta commented 5 months ago

What is the value of your redirectUri? It should match the route the LoginCallback is mounted on. In the screenshot, your app is loaded on your.domain?code=abcde..., but that should your.domain/sso/auth?code=abcde

PavankalyanPayyavula commented 5 months ago

I am wondering why it is working in local and not working in dev env.... const REDIRECT_URI = CLIENT_UI_ENDPOINT + 'sso/auth/' CLIENT_UI_ENDPOINT is my domain end point. I am changing my domain based on environment.

jaredperreault-okta commented 5 months ago

When your app runs on localhost, do you see the app get redirected to localhost:<port>/sso/auth? In the query params on the /authorize requests, what is the value of the redirectUri

Is it possible the host you're using isn't routing all traffic? When SPAs are hosted remotely, all traffic needs to be routed as a passthrough (usually with some sort of wildcard). You can test this by trying a random route. Based on your router config, if you navigate to {domain}/foo, it should render your 404 page. If it doesn't, that probably means your domain is routing all traffic to /

Edit: I expect localhost:<port>/foo to navigate to your 404 page

PavankalyanPayyavula commented 5 months ago

Yes, It is giving me 404 page when I tried with random route.

jaredperreault-okta commented 5 months ago

When your app runs on localhost, do you see the app get redirected to localhost:/sso/auth? In the query params on the /authorize requests, what is the value of the redirectUri

PavankalyanPayyavula commented 5 months ago

Oh sorry, here is the redirect_url redirect_uri: https://localhost:8081/sso/auth/

jaredperreault-okta commented 5 months ago

And you see the same behavior on your dev-*****-it domain?

dev-*****-it/foo renders 404?

redirect_uri is https://dev-*****-it/sso/auth?code=abcde

PavankalyanPayyavula commented 5 months ago

Hey @jaredperreault-okta sorry for disappearing for a while.

I think the redirect_uri is correct here. Screenshot 2024-03-29 at 12 35 26 PM

I am seeing this message in the console, I hope this might be helpfull for you to understand the issue more. index.js:635 [okta-auth-sdk] WARN: a saved auth transaction exists in storage. This may indicate another auth flow is already in progress.

jaredperreault-okta commented 5 months ago

I believe your problem has something to do with the routing of your hosted app (meaning the problem lies somewhere in the hosting architecture). Notice the url of page in the screenshot is {domain}/?code={authCode}, but the provided redirect_uri is {domain}/sso/auth.

If you look at the response of a /authorize request. You should see a 302 with a Location header of {domain}/sso/auth?code={authCode}, but it seems like you're landing on {domain}?code={authCode} instead, because the browser cannot navigate directly to /sso/auth

PavankalyanPayyavula commented 4 months ago

I have checked my hosting architecture, but I didn't find anything that causing this issue.

PavankalyanPayyavula commented 1 month ago

Hey @jaredperreault-okta , sorry for dragging you directly. I found that Vite is using rollup for build. Rollup is not able to import okta vue and okta auth. In local, Vite is using Esbuild for serve. So Okta process is working fine as expected.