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

Okta Auth JS library not redirecting to originalURI #1356

Closed
vikassharda opened this issue Nov 29, 2022 · 8 comments
Closed

Okta Auth JS library not redirecting to originalURI #1356

vikassharda opened this issue Nov 29, 2022 · 8 comments
Labels

Comments

@vikassharda
Copy link

Describe the bug?

Hi,

I have an existing VueJS 3.0 project that has only one page and I am trying to integrate it with Okta using @okta/okta-vue ^5.5.0 and @okta/okta-auth-js ^7.0.0 libraries. I am using TypeScript and VueJs 3.0 Composition API. I am trying it with Okta hosted login.

I am trying to load the application after user logs in via Okta but the application is always stuck at /login/callback URI that comes with code and state query strings. I can see the user information with parseFromUrl() function. I can also see original URI with oktaAuth.getOriginalUri() function but the request never lands that page.

I have gone through multiple Okta documentation and found that Okta library must be sending user to originalURI after a successful login but it's not happening in my case.

What is expected to happen?

I would like user to hit http://localhost:8080/form/company/1234 and redirect to Okta in case user wasn't authenticated earlier and it seems to be working fine but user is not returning to this URL after a successful Okta login.

What is the actual behavior?

Here is my router configuration:-
`const router = createRouter({

history: createWebHistory("/form/company"),
routes: [

{ path: '/login/callback', component: LoginCallback },
{
  path: '/:id',
  name: 'My Form',
  component: () => import(/* webpackChunkName: "Form" */ '../components/Form.vue'),
  meta: {
    title: 'My Form',
    requiresAuth: true,
  },
},

],
})

router.beforeEach(navigationGuard);

export default router;;`

Okta Auth configuration

export const oktaAuth = new OktaAuth({ issuer: 'something', clientId: 'removed', redirectUri: window.location.origin + '/login/callback', pkce: true, })

Here is my App.vue component
`export default defineComponent({
name: 'app',
components: {Header, Spinner},

setup(context, { expose }) {
function login() {
this.$auth.signInWithRedirect({originalUri: '/'})
}
onMounted(async() => {
const auth = getCurrentInstance().appContext.app.config.globalProperties.$auth

  const stManager = oktaAuth.authStateManager;
//It's always null
  console.log("Is it authstate"+ oktaAuth.authStateManager.getPreviousAuthState())
  auth.authStateManager.subscribe((authState) => {
  // Always null
    console.log("Subscribed "+authState.isAuthenticated);
  });
  const idToken = await auth.token?.parseFromUrl()
  .then(async res => {
    const { idToken } = res.tokens;
    const { accessToken } = res.tokens;
    const { userInfo } = res.tokens;

    console.log(`Hi ${idToken.claims.email}!`);
    console.log(`accessToken ${accessToken}!`);
    // Always prints the intended Uri e.g. '/1234'
    console.log(oktaAuth.getOriginalUri());
   //Goes in in finite loop between Okta and /login/callback if I push to original URI
    //router.push({ path: oktaAuth.getOriginalUri() })
    if (oktaAuth.isLoginRedirect()) {
      try {
        await oktaAuth.handleLoginRedirect();
      } catch (e) {
        // log or display error details
      }
    }
  })
})

},
})`

Reproduction Steps?

Not sure if it's a bug but I might be missing something here.

SDK Versions

"dependencies": {
"@okta/okta-auth-js": "^7.0.0",
"@okta/okta-vue": "^5.5.0",
"@vue/compat": "^3.1.0",
"vue": "^3.2.31",
"vue-router": "^4.0.3",
"dotenv": "^16.0.3"
}

"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-plugin-router": "~5.0.0",
"@vue/cli-plugin-typescript": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"@vue/compiler-sfc": "^3.1.0",
"eslint": "^7.32.0",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.0",
"eslint-plugin-vue": "^9.7.0",
"typescript": "~4.5.5",
"vue-loader-v16": "npm:vue-loader@^16.1.2"
},

Execution Environment

Chrome, Mozilla Firefox

Additional Information?

No response

@jaredperreault-okta
Copy link
Contributor

Have you tried passing the specific redirect path to signinWithRedirect?

this.$auth.signInWithRedirect({originalUri: '/form/company/1234'})

@vikassharda
Copy link
Author

Hi Jared,

Thanks for your response.

Yes, I have tried this but the web browser keeps refreshing between these two URLs. One is referencing login callback router under the root context of application i.e. http://localhost:8080/form/company and another one is referencing it directly under the host address i.e. http://localhost:8080/, see below

http://localhost:8080/form/company/login/callback?code=RClzjhn_YHxxB-R5tLAYJJhluioNczcjrdyd83vFoBE&state=uxlEr6RFRoOAMWsZGF5R8BLbToc1B5BSdBfjJU6bZCxn7oWqHXXFPLcZvhbz1HZ8

http://localhost:8080/login/callback?code=G3E1xUjxhfLMTI_NNNemZwokAbDu7HG2viePDjyPpN4&state=biZ3dzrqpOdZNHnEkLNDNoJuXICTKVYkBRNRigd0sRTVzVOOZ05lp3NKD7UUFJXN

This is what I have tried in my code and it's called after user is sent back to the application by Okta.

auth.signInWithRedirect({originalUri: "/form/company"+oktaAuth.getOriginalUri()})

Looks like Okta keeps appending the root context every time a refresh occurs. below is what I see in console when the code hits this line -> console.log(oktaAuth.getOriginalUri());
Console output
/cacform/company/cacform/company/cacform/company/cacform/company/cacform/company/1234

I also notice that both auth.token.isLoginRedirect() and authState.isAuthenticated() are always returning false.

Thanks,
Vikas

@jaredperreault-okta
Copy link
Contributor

Make sure your { path: '/login/callback', component: LoginCallback }, route is not gated by any authentication logic, it needs to handle the callback before isAuthenticated will return True. If the Callback component is gated by authentication logic an infinite loop will occur

@vikassharda
Copy link
Author

I don't think this route is gated by any authentication logic unless @okta/okta-vue is doing something under the covers.

isAuthenticated() method is called within the authStateManager subscribe so I am assuming that it should return true at some stage when its state changes.

auth.authStateManager.subscribe((authState) => { console.log("Is it authenticated "+authState.isAuthenticated); });

I see what you are saying that route should handle callback before any authentication logic is called but I don't have any logic.

Thanks

@vikassharda
Copy link
Author

Also, program always enters this if block since getPreviousAuthState() always returns null and triggers a browser refresh loop

    if (!auth.authStateManager.getPreviousAuthState()?.isAuthenticated) {
       oktaAuth.signInWithRedirect();
     }

@vikassharda
Copy link
Author

vikassharda commented Nov 29, 2022

So here is the thing. It works if I change my application base to "/" i.e. http://localhost:8080/ and now signInWithRedirect sends request to http://localhost:8080/ and I am able to navigate to http://localhost:8080/1234.

But it gets stuck at /login/callback URL as soon as I change the application base to 'form/company'. I even tried oktaAuth.signInWithRedirect({originalUri: '/form/company/1234'});

@willpercey-gb
Copy link

For me, I didn't have the correct implementation of vue-router, as soon as I implemented an empty front page with a <router-view/> component in it, it all started working.

@shuowu
Copy link
Contributor

shuowu commented Jan 25, 2023

Closing this issue, please re-open if needed

@shuowu shuowu closed this as completed Jan 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants