question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Custom provider with `pkce` and `state` checks but without `client_secret` possible?

See original GitHub issue

Question 💬

First: thanks a lot for your help! Really appreciate it. 🙏

My question: Is it possible to use a next-auth customprovider with pkce and state checks but without a client_secret? I couln’t figure it out. next-auth always asks for a secret. 🤔

background information

I try to use https://zitadel.ch and auth-next with a custom provider. I use the OIDC-flow with checks: ['pkce', 'state'] without a client_secret (as specified in: https://www.oauth.com/oauth2-servers/pkce/authorization-code-exchange/)

Even though a client_secret is not required by specification, next-auth wants one. (see error message in “How to reproduce”).

I’m not entirely sure but maybe the option I’m looking for is checks: ['pkce', 'state', 'nonce'] as discussed in https://github.com/nextauthjs/next-auth/pull/1565#issuecomment-804243981 but this seems not to be implemented.

All existing providers I looked at seem to want a client_secret even though it’s not best practice for SPA’s.

How to reproduce ☕️

  1. Create your own organisation at: https://accounts.zitadel.ch/register/org
  2. Create a project and an app with type web and the pkce flow
  3. Use the provided client_id together with this configuration:
export default NextAuth({
  providers: [
    {
      id: 'zitadel',
      name: 'zitadel',
      type: 'oauth',
      wellKnown: 'https://issuer.zitadel.ch',
      authorization: { params: { scope: 'openid email profile' } },
      idToken: true,
      checks: ['pkce', 'state'],
      profile(profile) {
        console.log(profile);
        return {
          id: profile.sub,
          name: profile.name,
          email: profile.email,
          image: profile.picture,
        };
      },
      clientId: process.env.ZITADEL_CLIENT_ID,
    },
  ],
});

Alltough a client_secret is officially not required, next-auth would like to have one:

[next-auth][error][OAUTH_CALLBACK_ERROR]
https://next-auth.js.org/errors#oauth_callback_error client_secret_basic client authentication method requires a client_secret {
  error: {
    message: 'client_secret_basic client authentication method requires a client_secret',
    stack: 'TypeError: client_secret_basic client authentication method requires a client_secret\n' +
      '    at Client.authFor (/Users/virth/git/smartive/customers/bin-eigenverlag/learnfox-backend/node_modules/openid-client/lib/helpers/client.js:135:15)\n' +
      '    at Client.authenticatedPost (/Users/virth/git/smartive/customers/bin-eigenverlag/learnfox-backend/node_modules/openid-client/lib/helpers/client.js:174:30)\n' +
      '    at Client.grant (/Users/virth/git/smartive/customers/bin-eigenverlag/learnfox-backend/node_modules/openid-client/lib/client.js:1327:46)\n' +
      '    at Client.callback (/Users/virth/git/smartive/customers/bin-eigenverlag/learnfox-backend/node_modules/openid-client/lib/client.js:472:35)\n' +
      '    at oAuthCallback (/Users/virth/git/smartive/customers/bin-eigenverlag/learnfox-backend/node_modules/next-auth/core/lib/oauth/callback.js:112:29)\n' +
      '    at async Object.callback (/Users/virth/git/smartive/customers/bin-eigenverlag/learnfox-backend/node_modules/next-auth/core/routes/callback.js:50:11)\n' +
      '    at async NextAuthHandler (/Users/virth/git/smartive/customers/bin-eigenverlag/learnfox-backend/node_modules/next-auth/core/index.js:133:28)\n' +
      '    at async NextAuthNextHandler (/Users/virth/git/smartive/customers/bin-eigenverlag/learnfox-backend/node_modules/next-auth/next/index.js:20:19)\n' +
      '    at async /Users/virth/git/smartive/customers/bin-eigenverlag/learnfox-backend/node_modules/next-auth/next/index.js:56:32\n' +
      '    at async Object.apiResolver (/Users/virth/git/smartive/customers/bin-eigenverlag/learnfox-backend/node_modules/next/dist/server/api-utils.js:102:9)',
    name: 'TypeError'
  },
  providerId: 'zitadel',
  message: 'client_secret_basic client authentication method requires a client_secret'
}

Contributing 🙌🏽

Yes, I am willing to help answer this question in a PR

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:1
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

12reactions
hboylancommented, Jan 26, 2022

So after messing around with the client provider config option, I was able to get this working with the following provider config in the test app.

Okta({
  clientId: process.env.OKTA_ID,
  clientSecret: process.env.OKTA_SECRET, // not set
  issuer: process.env.OKTA_ISSUER,
  checks: ["pkce", "state"],
  client: {
    token_endpoint_auth_method: "none",
  },
})

What do you all think about updating the config types so they no longer require clientSecret and merging the client options { token_endpoint_auth_method: 'none' } if not set? Or maybe this is something the underlying openid-client should handle?

5reactions
kramer99commented, Jan 26, 2022

@hboylan Thank you! I was stuck with the same issue using PKCE with Okta complaining about client_secret. I had resigned myself to using v3, but your config above worked for me with v4.1.2

Agree, this should be the default behaviour for PKCE providers, clientSecret should not be required.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Authorization Code Flow with Proof Key for Code Exchange ...
Learn how the Authorization Code flow with Proof Key for Code Exchange (PKCE) works and why you should use it for native and...
Read more >
Implement the OAuth 2.0 Authorization Code with PKCE Flow
This tutorial shows you how to migrate from the OAuth 2.0 Implicit flow to the more secure Authorization Code with PKCE flow.
Read more >
Do we really need client_secret to get access_token on PKCE ...
Using PKCE allows to make sure that the party trying to exchange the authorization code for the token is the one that actually...
Read more >
PKCE Support for Secret Clients with Spring Security - Baeldung
Learn how to enable OAuth's PKCE extension in a Spring Security application.
Read more >
Client Authentication vs. PKCE: Do you need both?
The short answer is: no. Should you still use client authentication where possible? Yes. At a high level, PKCE allows the authorization ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found