Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
PavankalyanPayyavula opened this issue Mar 18, 2024 · 12 comments
Labels
bug Something isn't working

Comments

@PavankalyanPayyavula
Copy link

PavankalyanPayyavula commented Mar 18, 2024

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 ----->

<script setup> import { onMounted, onUnmounted } from "vue"; import { useAuth } from "@okta/okta-vue"; import { debounce } from "lodash"; import axios from "axios";

import { useWindowSizeStore } from "./stores/modules/windowSize";
import { useLoggedInUserStore } from "./stores/modules/loggedInUser";
import { useCouponStore } from "./stores/modules/coupons";

const $auth = useAuth();
const loggedInUser = useLoggedInUserStore();
const coupons = useCouponStore();
const { setWidth } = useWindowSizeStore();

onMounted(() => {
$auth.authStateManager.subscribe(async (authState) => {
if (authState.isAuthenticated) {
const accessToken = $auth.getAccessToken();
axios.defaults.headers.common["Authorization"] = Bearer ${accessToken};
await loggedInUser.getLoggedinUserFromAPI().then(() => {
const rstarRoleType = loggedInUser.getRStarRoleType;
if (rstarRoleType === "CLIENT" || rstarRoleType === "ADMIN") {
coupons.getCoupons();
}
});
}
});
setWidth(window.innerWidth);
window.addEventListener("resize", setWindowWidth, false);
});

onUnmounted(() => {
window.removeEventListener("resize", setWindowWidth, false);
});

const setWindowWidth = debounce(() => {
setWidth(window.innerWidth);
}, 0.01);

</script> `

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

@PavankalyanPayyavula PavankalyanPayyavula added the bug Something isn't working label Mar 18, 2024
@jaredperreault-okta
Copy link
Contributor

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
Copy link
Author

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
Copy link
Contributor

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
Copy link
Author

PavankalyanPayyavula commented Mar 19, 2024

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
Copy link
Contributor

jaredperreault-okta commented Mar 19, 2024

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
Copy link
Author

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

@jaredperreault-okta
Copy link
Contributor

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
Copy link
Author

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

@jaredperreault-okta
Copy link
Contributor

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
Copy link
Author

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
Copy link
Contributor

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
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants