Get 500 error on client side but 403 in terminal for the backend

System Information
  • Strapi Version: 4.0.4
  • Operating System: Windows10
  • Database:
  • Node Version: 16.13.2
  • NPM Version: 8.1.2
  • Yarn Version:

Hi all.

So I’ve set up a frontend page with Next.js and a backend with Strapi. Still running local, cause I’m not done. Then i made my login page which do a request to a frontent api and futher to the strapi api: /api/auth/local. It works with the correct user, but when i try to login with non-existing user I get a 500 error “internal server error” on client side as response from /api/auth/local, but in the terminal where I have my backend running I get “Invalid identifier or password”. How do i get that message to the client? See pictures below:

Frontend code:

import { API_URL } from '@/config/index';

export default async (req, res) => {
    if(req.method === 'POST') {
        const { identifier, password } = req.body;

        const strapiRes = await fetch(`${API_URL}/api/auth/local`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                identifier, 
                password 
            })
        })

        const data = await strapiRes.json() // Returns 500 error

        if(strapiRes.ok) {
            //@toDo - Set Cookie
            res.status(200).json({user: data.user})
        } else {
            if(!identifier) {
                res.status(405).json({message: "Email is required to login"})
            } else if(!password) {
                res.status(405).json({message: "Password is required to login"})
            } else {
                res.status(data.error.status).json({message: data.error.message})
            }
            
        }

        res.status(200).json({});
    } else {
        // res.setHeader('Allow', ['POST'])
        res.status(405).json({message: `Method ${req.method} not allowed`});
    }
}

Terminal:

2 Likes

Same issue for me. Basically, Strapi returns 500s for most kinds of errors instead of 401, 403, etc… Any way to reconfigure this and make sure front end gets real error codes?

4 Likes

Hi, I have the same issue here, pretty hard to make a nice UX if all error codes returned are 500s :frowning:

1 Like

I am facing the same issue now (strapi v4.3.8),all errors (including auth failure/forbidden access ,etc.) were returned with code 500 and message ‘Internal Server Error’

2 Likes

hello guys, were you able to fix this issue?? please reply!

1 Like

got the same issue with v4.4.0. Any feedback?

1 Like

I tracked the strapi codes.
The @strapi/plugin-users-permissions/server/controllers/auth.js callback function throw the ValidationError

throw new ValidationError('Invalid identifier or password');

I debuged

console.log(error instanceof ValidationError); // it returns "true" 

in auth.js.

But there is issue in the strapi error middlewares handler : @strapi/strapi/lib/middlewares/errors.js

      console.log("---------");
      console.log(error instanceof Error); // it returns true
      console.log(error instanceof ApplicationError); // it returns false instead of true !!!
      console.log(error instanceof ValidationError); // it returns false instead of  true  !!!
      console.log("---------");

so it formatInternalError.
I don’t know why

      console.log(error instanceof ApplicationError); // it returns false
      console.log(error instanceof ValidationError); // it returns false
2 Likes

just updated to 4.4.6 and problem is gone,

{"data":null,"error":{"status":400,"name":"ValidationError","message":"Invalid identifier or password","details":{}}}%
1 Like

I’ve updated to v4.4.6 but the issue is still there

2 Likes

My workaround here was to overwrite functions and replace ValidationError and ApplicationError code with:

      return ctx.badRequest("The error message");

An ugly solution though.

Same for me, strapi version 4.4.7

Same issue here, using strapi 4.5.1

Has anyone found a good solution for this issue?

Having the same issue. Did anyone fix this?

Same issue here, I tried to debug Strapi but ended up just like MilenaPetkanova. No real solution

I’m going to add to this, been trying to debug logging in with /api/auth/local for 2 days, trying various methods, which either produce a 400, 401 or the 500 error message. Also tried the “new FormData()” method for my data and I just can’t get this to work.

const result = await fetch( ``${API_URL}/api/auth/local`, {
	method: 'POST',
    body: JSON.stringify( {
    	'identifier': username,
		'password': password
    } )
} );

const result = await fetch( ``${API_URL}/api/auth/local`, {
	headers: {
      'Content-Type': 'application/json'
    },
    method: 'POST',
    body: JSON.stringify( {
    	'identifier': username,
		'password': password
    } )
} );

const result = await fetch( ``${API_URL}/api/auth/local`, {
	headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    method: 'POST',
    body: JSON.stringify( {
    	'identifier': username,
		'password': password
    } )
} );

axios.post( `${API_URL}/api/auth/local`, {
	'identifier': username,
	'password': password
} )

axios.post( `${API_URL}/api/auth/local`, JSON.stringify( {
	'identifier': username,
	'password': password
} ) )

as mentioned in thread, is seems the 400 error message seems to be “identifier and password” required message. My 500 message is giving me this error:

[2023-02-24 17:37:39] [2023-02-24 17:37:39.192] error: "jwtSecret" is not allowed in "options"
[api] [2023-02-24 17:37:39] Error: "jwtSecret" is not allowed in "options"
[api] [2023-02-24 17:37:39]     at /workspace/node_modules/jsonwebtoken/sign.js:45:17
[api] [2023-02-24 17:37:39]     at Array.forEach (<anonymous>)
[api] [2023-02-24 17:37:39]     at validate (/workspace/node_modules/jsonwebtoken/sign.js:41:6)
[api] [2023-02-24 17:37:39]     at validateOptions (/workspace/node_modules/jsonwebtoken/sign.js:56:10)
[api] [2023-02-24 17:37:39]     at Object.module.exports [as sign] (/workspace/node_modules/jsonwebtoken/sign.js:165:5)
[api] [2023-02-24 17:37:39]     at Object.issue (/workspace/node_modules/@strapi/plugin-users-permissions/server/services/jwt.js:33:16)
[api] [2023-02-24 17:37:39]     at Object.callback (/workspace/node_modules/@strapi/plugin-users-permissions/server/controllers/auth.js:90:32)
[api] [2023-02-24 17:37:39]     at runMicrotasks (<anonymous>)
[api] [2023-02-24 17:37:39]     at processTicksAndRejections (node:internal/process/task_queues:96:5)
[api] [2023-02-24 17:37:39]     at async returnBodyMiddleware (/workspace/node_modules/@strapi/strapi/lib/services/server/compose-endpoint.js:52:18)

This seems to indicate it’s having issues with the jwtSecret. I’m hosting on Digital Ocean, so now I’m making sure my environment variables are all set correctly and rebuilding…

They are.

So, now comes the tedious process of debugging the code. I loaded the API server locally and started tracing files, putting console logs starting with auth.js, then jwt.js. This is where I discovered my issue:

In jwt.js, line 38, they are passing 3 parameters to the jwt.sign() function. The 3rd parameter appears to be options. And Strapi is passing the “jwtSecret” key:value.

jsonwebtoken (npm package that has function jwt.sign) has a function to validate passed options… and “jwtSecret” is not one of the valid options, so it’s throwing and error, which in turn, Strapi is not handling properly so it’s throwing a 500 error.

I manually changed the 3rd option from:

return jwt.sign(
      _.clone(payload.toJSON ? payload.toJSON() : payload),
      strapi.config.get('plugin.users-permissions.jwtSecret'),
      jwtOptions
    );

to

return jwt.sign(
      _.clone(payload.toJSON ? payload.toJSON() : payload),
      strapi.config.get('plugin.users-permissions.jwtSecret'),
      {
        'expiresIn': jwtOptions.expiresIn || '30d'
      }
    );

…since it only appears to be sending the expiresin option. And now it’s working.

Not sure if this fix applies to you guys, but after two days of debugging, figured I would share.

I would like to add, that the correct call for me (at least one that provided results after the hack/fix) was:

const data = JSON.stringify( {
  identifier,
  password
} );

const res = await fetch( `${API_URL}/api/auth/local/`, {
  headers: {
    'Content-Type': 'application/json'
  },
  method: 'POST',
  body: data
} );

And this issue apparently has to do with the upgrade from v8 to v9 for the jsonwebtoken package. There’s a migration guide that explains that they are now validating options.

To follow up on this… my issues turned out to be a bad formatted plugin config file. I had:

'users-permissions': {
  config: {
    jwt: {
      jwtSecret: env('JWT_SECRET'),
    }
  },
},

Instead of:

'users-permissions': {
  config: {
    jwtSecret: env('JWT_SECRET'),
  },
},

So it was merging the jwtSecret with the jwt options which get sent to jsonwebtoken. jwtSecret is not a valid option, so jsonwebtoken was throwing an error back to Strapi.

Hello, I had the same problem so ApplicationError, ValidationError returned an error 500, I removed @strapi/utils from my package.json and it worked again . I didn’t investigate further, hoping that it will help someone

Was anyone able to find a proper solution for this issue?