400 Bad Request if Authorization Bearer token used

2019-05-25 20:52发布

问题:

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?

回答1:

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:

  1. 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.

  2. 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.



回答2:

@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!