denoland / deno_kv_oauth

High-level OAuth 2.0 powered by Deno KV.

Home Page:https://jsr.io/@deno/kv-oauth

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Implement session revocation

jtoppine opened this issue · comments

Signout function here only deletes the session locally on the server, but does not actually revoke the authentication with the provider: https://github.com/denoland/deno_kv_oauth/blob/main/lib/sign_out.ts

This causes browser to remember earlier credentials even after signout, so that when any user tries to sign in again using the same computer, the earlier authentication is just renewed without any prompt.

You can work around this issue, at least when using Auth0 provider, with the prompt parameter: const response = signIn(request, oauthConfig, { urlParams: {prompt: "login"}});
This forces the provider to present the login screen again every time signin is called, even if there is a previous session left dangling. This is not secure however, as really the session should be revoked with the provider upon signout..

I recall that token revocation still needs to be supported in the underlying OAuth module, which is a blocker. I raised an issue requesting the functionality to be added. There are two solutions:

  1. Add support for token revocation in the OAuth module.
  2. Switch the OAuth module to something that supports token revocation, like https://github.com/panva/oauth4webapi. This might be the best path forward for token revocation and other features like OpenID Connect.

We might discuss this and come back to you. We may have to live without token revocation for the time being.

Thank you. Good to know about oauth4webapi, that seems like it might be a nice lower level alternative to fall back to if it comes to that.

For anyone struggling with the same issue, here's how to actually sign out (when using Auth0 provider, but other providers probably work in similar manner), while still working with deno_kv_auth:

// these are probably already defined where you have set up your oauthConfig object for deno_kv_auth, included here for clarity
const domain = "MY_AUTH0_DOMAIN";
const returnTo = encodeURIComponent("URL_TO_RETURN_AFTER_SUCCESS");
const clientId = encodeURIComponent("MY_OAUTHCONFIG_CLIENT_ID");
    
const url = `https://${domain}/v2/logout?client_id=${clientId}&returnTo=${returnTo}`;

// here we get the would-be-signout-response from deno_kv_auth, which would delete the cookie from user and redirect to the success url....
const response = signOut(request, oauthConfig);

// ...but we don't return it as is, but instead change the success url redirect to point to the Auth0 logout endpoint instead, which then redirects user back to our actual success url
response.headers.set("Location", url);

// ok
return response;

In addition, you may want to use the forced login prompt mentioned earlier upon signIn, however this may hide any issues you may have with the signOut procedure, so use with caution:

const response = signIn(request, oauthConfig, { urlParams: {prompt: "login"}});

Disclaimer: this seems to work, but I'm not an auth expert so can't give any guarantees about correctness or compliance with "best practices"

Hi @jtoppine @iuioiua,

I would like to work on this task If you are aligned on the approach.

Would be glad if you give me some more context on Slack.

Hi @raashidanwar, we can take one of two paths:

  1. Rework this module to work with x/oauth4webapi. This is a decently-sized undertaking but could reap other benefits throughout the module as x/oauth4webapi is a comprehensive and extensive library.
  2. Contribute to x/oauth2_client, implementing token revocation there and adjusting this module to take advantage of that. The main problem is the latency in applying upstream changes.

We have yet to decide on this, but I would happily discuss it further. I don't use Slack, but I am on Discord under the same username. If you haven't already, you might want to join Deno's Discord server.