Skip to content
This repository has been archived by the owner on Jan 26, 2025. It is now read-only.

Is there a way to log out / logoff a session using the middleware? #162

Closed
Shogan opened this issue Mar 25, 2018 · 17 comments
Closed

Is there a way to log out / logoff a session using the middleware? #162

Shogan opened this issue Mar 25, 2018 · 17 comments
Assignees

Comments

@Shogan
Copy link

Shogan commented Mar 25, 2018

Hi there,

Is there any way to easily log out a session when using the okta oidc middleware?

I've been trying to implement logout functionality, and am using this middleware for my node application, however the only way I have found so far is to use the API and pass in a token_id, however if we can't get this, we can't use this API endpoint. This forum post indicates its not possible to get the token_id using this middleware due to its design: https://devforum.okta.com/t/how-to-get-access-and-id-token-from-oidc-object-when-using-okta-oidc-middleware-node-module/737/5

The API endpoint for oidc logout that requires the token_id is documented here: https://developer.okta.com/docs/api/resources/oidc#logout

Thanks

@Shogan
Copy link
Author

Shogan commented Apr 5, 2018

Just to clarify, I've tried updating to 0.1.1 and still get this same issue.

I'm also using the logout example direct from the nodejs middleware example provided on the main page:

app.get('/logout', (req, res) => {
  req.logout();
  res.redirect('/');
});

@robertjd
Copy link
Contributor

robertjd commented Apr 6, 2018

HI @Shogan , thanks for the question. Your findings are correct at the moment. We have a task for this month to clean up our logout story to make this easier/possible/more obvious (Okta session logout vs local express session destroy). In the meantime I dont see a great workaround, unfortunately. If you want to get the ID token manually to manually pass it to the logout endpoint.. I think you'd probably have to re-implement the callback handler, which delegates the code exchange down to passport: https://github.com/okta/okta-oidc-js/blob/master/packages/oidc-middleware/src/connectUtil.js#L83

@redbmk
Copy link

redbmk commented May 16, 2018

I found a workaround for now. It's not ideal and probably missing some edge cases, but this can be done with a little javascript. It's possible a popup blocker would prevent this, but it at least works in Chrome. I paired this with the /logout route that @Shogan mentioned (which is also in the middleware docs).

<a href="/logout" id="logout-button">Sign out</a>
<script>
  document.getElementById('logout-button').addEventListener('click', (event) => {
    event.preventDefault()

    const signoutWindow = window.open(
      'https://organization.url/login/signout',
      'okta-signout',
      'height=1,width=1',
    )

    setTimeout(() => {
      signoutWindow.close()
      window.location = document.getElementById('logout-button').href
    }, 1000)
  })
</script>

This opens a new window that signs you out of Okta, then closes it immediately. This can't be an iframe unfortunately, since it's from a different origin. You also can't use the load event for the same reason, hence just waiting for a second before closing the window. You'll get a small popup window that closes after a second, then the page continues to go to the /logout path. Next time you go to log in you should get a sign-in page.

I think the biggest edge case here is assuming that the page will successfully log you out in one second. If you have a really slow internet connection, this may not be the case. You could do this without the setTimeout, and it will sometimes work, but you'll have more success the longer you wait.

@thomashibbard
Copy link

@Shogan

use the API and pass in a token_id

Can you elaborate on exactly the format of the address you are using to do this? I am hitting something like this:

https://dev-{account id}.oktapreview.com/v1/logout?id_token_hint={long id_token}&post_logout_redirect_uri=http://localhost:8080/logged-out

and I just end up on a 404 at the okta site. Have you constructed this URL some other way?

@Shogan
Copy link
Author

Shogan commented Sep 26, 2018

Hi @thomashibbard

It's been a while, but the format I was using to test was https://dev-xxxxxx.oktapreview.com/oauth2/default/v1/logout?id_token_hint=xxxxx.

Not sure if I had any sucess with that or not though. I think it is meant to return a 204 No content status if successful.

@kaspesla
Copy link

This this ever get figured out? Can we log people out with okta oidc middleware?

@jmelberg-okta
Copy link
Contributor

With the release of @okta/[email protected], you now have the ability to extract the idToken from the user context. This will allow you to terminate the user's SSO session within Okta by hitting the end session endpoint (/logout).

In your logout handler, you'll want to do two things:

  1. Terminate your local user session
  2. Redirect your user to Okta via the end_session_endpoint.

This will look similar to:

// The idToken of the user
const idToken = req.userContext.tokens.id_token;

// Remove the local session
req.logout();
   
// Location to redirect to after the logout has been performed. (Must be whitelisted)
const postLogoutUri = 'https://mysite.com/home';

const endSessionEndpoint = `https://{yourOktaDomain}/logout` +
  `?id_token_hint=${idToken}` +
  `&post_logout_redirect_uri=${postLogoutUri}`;

// Redirect the user to the endSessionEndpoint URL
res.redirect(endSessionEndpoint);

In my opinion, the oidc-middleware library should provide a clean interface for local logout (req.logout()) and SSO session termination. Further, if an accessToken and/or refreshToken was minted, these will need to be revoked prior to terminating the local session.

I'm going to label this issue as an enhancement so we can prioritize adding this feature.

@kaspesla
Copy link

kaspesla commented Oct 15, 2018 via email

@kaspesla
Copy link

kaspesla commented Oct 17, 2018 via email

@jabas06
Copy link

jabas06 commented Oct 19, 2018

@kaspesla, I was running into the same issue. The logout endpoint has to include the complete Base URL, like this:

const endSessionEndpoint = `https://{yourOktaDomain}/oauth2/default/v1/logout` +
  `?id_token_hint=${idToken}` +
  `&post_logout_redirect_uri=${postLogoutUri}`;

@redbmk
Copy link

redbmk commented Oct 22, 2018

@jmelberg-okta thanks for the tips! Another thing that took me a while to figure out I needed was to add an authorized Logout Redirect URI.

image

It turns out this can't be done when creating the application in Okta, but can be done when editing it after creation. I think it should be both be there during app creation as well as have a default value. Having req.logout() handle all this automatically for you would be awesome, and having an automatic /logout route would be cool too, just as there's already an automatic /login route.

@jmelberg-okta
Copy link
Contributor

@redbmk - You are correct. Using the App Wizard UI, you cannot set a Logout redirect URI when creating an application.

This is an enhancement our team is going to implement once we have a better story around logout in these integration libraries.

@thomashibbard
Copy link

thomashibbard commented Oct 23, 2018 via email

@hardpbl
Copy link

hardpbl commented Oct 31, 2018

I have problem ,Why did I pass "https://dev-xxxxxx.oktapreview.com/oauth2/default/v1/logout?id_token_hint="+idToken receive is 403 ,This android app can't logout.

@anilpai
Copy link

anilpai commented Nov 12, 2018

Logging out / revoking a token is such a pain in Okta OAuth

@swiftone
Copy link
Contributor

swiftone commented Feb 5, 2019

Version 2.0.0 of @okta/oidc-middleware now supplies a POST-based /logout route that logs the user out from Okta(for this browser), not just from the local application.

@StefanoSega
Copy link

@swiftone sorry, I tried out with middleware v2 but hitting /logout it logs the user out of Okta but it doesn't clear the session and after redirect the user is still logged in and not redirected to Okta login page.
I tried also creating a custom endpoint logout-test but is the same, it doesn't destroy the session.

This is roughly the first part of my code:

const app = new Express();

app.use(
  require('express-session')({
    secret: 'express session secret',
    resave: true,
    saveUninitialized: false
  })
);

const oidc = new ExpressOIDC({
  issuer: `https://XXXXXX.okta.com/oauth2/default`,
  client_id: 'XXXXXXXXX',
  client_secret: 'XXXXXXXXX',
  redirect_uri: `http://localhost:8080/authorization-code/callback`,
  scope: 'openid profile',
  appBaseUrl: 'http://localhost:8080'
});
app.use(oidc.router);
app.post('/logout-test', (req, res, next) => {
  oidc.forceLogoutAndRevoke();
  req.logout();
  req.session.destroy(function(err) {
    res.redirect('/users');
  });
});
app.use('/users/:id?', oidc.ensureAuthenticated() , (req, res, next) => {
  console.log(req.userContext);
  console.log(req.baseUrl);
  console.log(req.originalUrl);
  next();
});

hitting /users req.userContext is always valorized even after hitting POST /logout and refreshing, but once hit /logout I'm kicked out of Okta.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests