Securing Electron Applications with OpenID Connect and OAuth2

Hi there,
I am following the steps to implement auth0 into an electron app. I am having an issue after the user signs up and the event gets fired that passes the callback URL to the auth service loader.

when I post the exchange options to /oauth/token it is responding with an error

Its not redirecting to the electron application

Doesnā€™t this guide violate the best practices for native apps: to run auth through the userā€™s browser?

I outlined an alternate approach here: Using Auth0 with Tauri - DEV Community . It talks about doing it with Tauri, but you could also add a protocol handler to your Electron app and do the same thing.

Hey @RandomEngy,
Your concern is legitimate but the topic is a bit controversial for desktop applications.
To learn more about this, please read the following thread and/or watch this video .

Thank you for sharing! :pray:

@andrea.chiarelli Thanks for the pointer. Though a couple things are a bit dated on the reasoning there. One is that in 2023 mainstream support for browser auth on desktop is more prevalent. Slack does auth through the system browser, though it renders its UI through WebViews. Visual Studio has an option to auth through the browser. VSCode also does its auth through the browser when you choose GitHub auth mode. The talk about needing a localhost server for the return URL doesnā€™t apply when you use a protocol handler on your app. And Iā€™m pretty sure that in most cases the system can bring the browser to the foreground when an app launches a URI through the shell.

I canā€™t speak entirely to the claim that itā€™s easy for any app to steal passwords from the system browser on the desktop, but just from a usability point of view, letting the user access their already signed-in state and have standard access to their in-browser or 3rd party stored passwords is really nice.

I do realize that itā€™s more complicated on Desktop than on Mobile, but I think the way the winds are blowing is toward in-browser auth.

And just tried the latest Visual Studio: You click Sign In and it launches in the system browser to sign in with your Microsoft Account.

Hey @RandomEngy,
You are totally right. The current trend goes towards using the system browser.
Actually I was just pointing out that the positions within the OIDC community are not so clear-cut.
After all, itā€™s a matter of balancing user experience and security.

How should I integrate auth when i want to use @auth0/auth0-react? I have tried three ways and they all fail at different stages.

  1. use localhost redirect_uri. f.e redirect_uri: http://localhost:5173/callback. Iā€™ll redirect to index.html with searchParams.
mainWindow.webContents.on('will-redirect', (event, url) => {
    if (url.startsWith('http://localhost:5173/callback')) {
      event.preventDefault()
      const search = url.split('?')[1]

      const newUrl = join(__dirname, `../renderer/index.html`)
      mainWindow.loadFile(newUrl, { search }).catch((error) => {
        console.error(`Failed to load URL: ${error.message}`)
      })
    }
  })

This logs in properly ā†’ library says user is authenticated ā†’ redirects properly. But after redirecting to a protected page, the library suddenly canā€™t get the auth data. F.e the user is nullish in const { user } = useAuth0.

  1. redirect_urifile://callback. Handle will-redirect like in step 1. This fails at https://auth0..../authorize/resume 302 redirect and throws net::ERR_UNSAFE_REDIRECT in chrome devtools. When I relaunch the app, the user is logged in tho. So it almost works as well.

  2. Register and use a custom protocol such as redirect_uri: myapp//callback. This fails at redirect because myapp://callback not a proper url.

Hi @kaspar , welcome to the Auth0 Community.

Iā€™d like to understand your scenario a bit more before I can give you further recommendations. How are you planning on authenticating your users? Are you using a redirect? a pop up? an external browser?

For React I havenā€™t used the redirection as it can cause some issues with Electron, but rather I have implemented it using the method loginWithPopup from the Auth0 SDK.

If you follow that implementation it will be much easier for you, unless you want to use the system browser (similar to what slack, or zoom do).

Thanks!

1 Like

Just leaving this here for anyone who might run into the same issue

If you get this error: TypeError: jwtDecode is not a function

Replace this piece of code inside auth.service.js:
const jwtDecode = require('jwt-decode');

with this one:
const { jwtDecode } = require('jwt-decode');

And it should get rid of the error :))

Thanks @arnes for sharing your solution.

Iā€™ll revise this article and correct anything that maybe wrong.