Zala Nilesh
Zala Nilesh

Reputation: 41

JWT_SESSION_ERROR in next auth with next.js

In local devlopment signin is working fine but Below error is thorwn by next-auth while returing from our custom oauth provider with production build at dev url like https://dev-app.xyz.com

NEXTAUTH_SECRET and NEXTAUTH_URL env variable is also set as per this https://next-auth.js.org/deployment

` authError { code: 'JWT_SESSION_ERROR', metadata: { code: 'ERR_JWE_DECRYPTION_FAILED', name: 'JWEDecryptionFailed', message: 'decryption operation failed',

} }`

pacakge Versions

` "dependencies": {

"@mui/icons-material": "^5.10.14",
"@mui/x-data-grid": "^5.17.14",
"@sentry/nextjs": "^7.23.0",
"@reduxjs/toolkit": "^1.9.1",
"applicationinsights": "^2.3.6",
"axios": "^1.2.0",
"moment": "^2.29.4",
"moment-timezone": "^0.5.38",
"net": "^1.0.2",
"next": "13.0.4",
"next-auth": "^4.18.4",
"nextjs-redirect": "^6.0.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-intl": "^6.2.1",
"react-redux": "^8.0.5",
"react-test-renderer": "^18.2.0",
"tls": "^0.0.1",
"v8": "^0.1.0"

}, `

[...nextauth].ts is below

export default async function auth(req: NextApiRequest, res: NextApiResponse) {
    if (!config?.payload) {
        try {
            const response = await fetch('url to fetch config dyamic');
            config = await response.json();
          
        } catch (error) {
            if (error) {
               
            }
        }
    }
    try {
        return await NextAuth(req, res, {
            providers: [
                {
                    id: appConst.OAUTH_ID,
                    name: 'Demo',
                    type: 'oauth',
                    checks: ['pkce', 'state'],
                    idToken: true,
                    wellKnown: `${config.payload.idtAuthorityUrl}${apiUrls.IDT_WELLKNOWN}`,
                    authorization: {
                        params: {
                            scope: config.payload.webAppIdtClientScope,
                        },
                    },
                    clientId: config.payload.webAppIdtClientId,
                    profile(profile) {
                        return {
                            id: 1,
                            ...profile,
                        };
                    },
                    clientSecret: config.payload.webAppIdtClientSecret,
                },
            ],
            pages: {
                signIn: apiUrls.AUTH_ERROR,
            },
            secret: process.env.NEXTAUTH_SECRET,
            debug: false,
            session: {
                strategy: 'jwt',
            },
            jwt: {
                secret: process.env.NEXTAUTH_SECRET
            },
            useSecureCookies: true,// using false while local development
            logger: {
                error(code, metadata) {
          
                    // eslint-disable-next-line no-console
                    console.log('authError', { code, metadata });
       
                },
            },
            callbacks: {
                async jwt({ token, account }) {
                    if (account) {
                        token.accessToken = account.access_token;
                        token.accessTokenExpire = account.expires_at
                            ? account.expires_at * 1000
                            : 0;
                        token.refreshToken = account?.refresh_token;
                        token.id_token = account?.id_token;
                        token.accessTokenIssuedAt = Date.now();
                    }
                    //  return token if not Access token expired
                    if (
                        token.accessTokenExpire &&
                        Date.now() < token.accessTokenExpire
                    ) {
                        return token;
                    }
                    //  Access token has expired, try to update it
                    return await getAccessToken(token, config.payload);
                },
                // eslint-disable-next-line require-await
                async session({ session, user, token }) {
                    if (token && typeof token.accessTokenExpire === 'number' && typeof token.accessTokenIssuedAt === 'number') {
                        const tempsession: any = session;
                        // session interval in seconds, It's accesstoken expire - 10 minutes
                        let interval = Math.round(((token.accessTokenExpire - token.accessTokenIssuedAt) - (60000 * 10)) / 1000);
                        if (interval < 300) {
                            interval = 2
                        }
                        tempsession.interval = interval;
                        return tempsession;
                    } else {
                        return session;
                    }
                },
            },
        });
    } catch (error) {
        if (error) {
   
            console.log('NextAuth', error);
          
        
        }
    }
}

Upvotes: 4

Views: 5631

Answers (2)

Afaq Ahmad
Afaq Ahmad

Reputation: 71

If you face any of the following errors, Follow these steps and the error will be fixed as My one was fixed.

1. code: 'JWT_SESSION_ERROR' name: 'JWEDecryptionFailed

2. MissingSecret [MissingSecretError]: Please define a `secret` in production.

3.ERROR[next - auth][error][NO_SECRET];

Step 1 Generate a secret:

To do this, open a terminal under Linux (In Window Open Hyper or CMD) and type : openssl rand -base64 32 The output of this order will be your secret, a string like : Ey7nTKnggBc0bRN8WUjyShw2qzOZ6KW4fUyqcKBePxY=

2- Place this secret in an environment variable:

I recommend you to put this secret in an environment variable. You can use the .env file (or .env.local) or directly your next.config.js file. Here I take the example of the next.config.js file that I prefer to work with. In this file, add the line with the value NEXTAUTH_SECRET and your secret. My Example in .env file: NEXTAUTH_SECRET='78zFZvyspgAIBXPKdA0AhFqcNWXX16/CEmBFOHU3iOg='

3- Adding the secret in the next-auth configuration:

Once your secret is set as an environment variable, next-auth must be able to access it. Under NextJS, environment variables are accessible on the server side through the process.env object and it is the NEXTAUTH_SECRET property that we are interested in here, On your application, go to the file /pages/api/auth/[...nextauth].js, and add at the same level as providers and your possible callbacks, the value:

secret: process.env.NEXTAUTH_SECRET,

4- Relaunch a build:

Finally, remember to run a new npm run build and you’re all set 🥳 !

Upvotes: 7

Jsinh
Jsinh

Reputation: 2579

This might be due to restrictions at the web server level in the hosting environment. Assuming you are using NodeJS and NextJS and running a web proxy behind Nginx or Apache.

In OAuth 3-legged process OAuth identity server sends data back. In case when the Authorize response callback URL - body or headers is too large or big, then what your hosting environment supports may give errors.

Check web server logs and tweak the config for proxy-body-size, proxy-buffer-size, fastcgi-buffer-size etc, in the case of Nginx and see if it helps.

Suggesting based on the mention that it works locally but shows an error in deployed version

Upvotes: 0

Related Questions