I'm using PostMan to troubleshoot an odd 400 error with my Angular / NodeJS app.
I'm trying to GET https://example.com/login.html
and the request has two headers:
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGc...==
and Accept: text/html
This returns a 400 Bad Request
error (server: cloudflare-nginx)
This works fine (returns 200
) if:
I access the file in my local environment on
http://localhost:5000/login.html
(no https factor?) -or-I remove
Authorization: Bearer
from the header
If I watch my NodeJS server logs, I don't even see the request come through. So /login.html
doesn't even get hit, I assume because Express is rejecting it before my app.use(logger('dev'));
picks it up.
UPDATE: I believe Cloudflare is kicking it back with 400 prior to the request ever reaching Heroku.
A few more points:
I am using JWT to authenticate users, which is where the Bearer token comes from.
If I access other endpoints, such as
/profile
with the Bearer token, it responds properly with the user profile from decoding the token.
My question is:
Why would this request be a "Bad Request" when it works on other endpoints?
Is there a way to catch this and do something with the request before it's returned as 400?
@James, I don't have enough reputation to post a comment on your answer, but I thought it would be helpful to others struggling with this issue to state that your suggestion to reduce the complexity/size of the signed user indeed resulted in resolving similar issues I was experiencing. This was on my list of performance optimizations anyway - but it didn't occur to me that it could be a cause for error in this scenario - so you deserve the credit... thanks!
For readers - there are some useful links in this SO thread about max size for tokens: What is the maximum size of JWT token?
And this is a tool I use to check the validity of a generated tokens... https://www.base64decode.org/
Hope this justifies the upgrade from comment to answer!
As it turns out, the issue was related to my implementation of JWT. For some reason, one user continued to receive a token that caused these 400 errors, even though the token was verified as valid using JWT.io.
I made two significant changes that fixed the issue:
I was embedding the full user profile (long JSON) in the token payload. I reduced it to just their userid, both for performance reasons (far smaller size) and just in case something in the complex payload was causing the issue.
I switched from JWT-Simple to
jsonwebtoken
in my node implementation.I'm just glad that worked. My next step was to switch from 'Authorization' to 'x-encoded-auth' or some other custom name.