Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem decoding token #319

Closed
Oxyrus opened this issue Dec 15, 2017 · 9 comments
Closed

Problem decoding token #319

Oxyrus opened this issue Dec 15, 2017 · 9 comments

Comments

@Oxyrus
Copy link

Oxyrus commented Dec 15, 2017

Hello, thanks for making pyjwt!

I've been trying to use it in my Django application, however, something weird is happening: I can't decode the token!

This is how I'm creating the token

token = jwt.encode({
    'user_id': user.id
}, key='secret', algorithm='HS256')

And creating a token with user_id: 1 gives me this token b'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxfQ.J_RIIkoOLNXtd5IZcEwaBDGKGA3VnnYmuXnmhsmDEOs', however it says invalid signature in https://jwt.io/ for some reason.

Trying to decode my token in the server throws this error:

Traceback (most recent call last):
  File "/home/andres/venv/zyru/lib/python3.6/site-packages/jwt/api_jws.py", line 170, in _load
    header_data = base64url_decode(header_segment)
  File "/home/andres/venv/zyru/lib/python3.6/site-packages/jwt/utils.py", line 42, in base64url_decode
    return base64.urlsafe_b64decode(input)
  File "/home/andres/venv/zyru/lib/python3.6/base64.py", line 133, in urlsafe_b64decode
    return b64decode(s)
  File "/home/andres/venv/zyru/lib/python3.6/base64.py", line 87, in b64decode
    return binascii.a2b_base64(s)
binascii.Error: Incorrect padding

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/andres/Code/Python/zyru-api/members/schema.py", line 41, in get_user
    decoded = jwt.decode(token, 'secret')
  File "/home/andres/venv/zyru/lib/python3.6/site-packages/jwt/api_jwt.py", line 70, in decode
    payload, signing_input, header, signature = self._load(jwt)
  File "/home/andres/venv/zyru/lib/python3.6/site-packages/jwt/api_jws.py", line 172, in _load
    raise DecodeError('Invalid header padding')
jwt.exceptions.DecodeError: Invalid header padding

Why is the exception happening?

Thanks a lot!

@vimalloc
Copy link
Contributor

vimalloc commented Dec 15, 2017

Try decoding the token to utf-8:

jwt.encode(data, secret, algorithm).decode('utf-8')

In jwt.io, you need to get rid of the b'' part of the string. That indicates that it is a byte string, and is not actually part of the token.

@Oxyrus
Copy link
Author

Oxyrus commented Dec 15, 2017

Didn't work @vimalloc here's the code I'm using:

def get_user(info):
    token = info.context.META.get('HTTP_AUTHORIZATION')

    if not token:
        return

    try:
        decoded = jwt.decode(token, 'secret', 'utf-8') # Decoding here
        user = User.objects.get(pk=decoded['user_id'])
        return user
    except:
        raise Exception('User not found')

I'm definitely getting the token, because if I check with:

def get_user(info):
    token = info.context.META.get('HTTP_AUTHORIZATION')
    print(token)

I get it printed in the console

System check identified no issues (0 silenced).
December 15, 2017 - 01:16:27
Django version 2.0, using settings 'zyru.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
b'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxfQ.J_RIIkoOLNXtd5IZcEwaBDGKGA3VnnYmuXnmhsmDEOs'

@vimalloc
Copy link
Contributor

vimalloc commented Dec 15, 2017

This isn't right:

decoded = jwt.decode(token, 'secret', 'utf-8')

You want to create the token like such:

# The decode call here doesn't decode the jwt, it converts the encoded jwt from
# a byte string to a utf-8 string.
data = {'foo': 'bar'}
encoded_token = jwt.encode(data, 'secret', 'HS256').decode('utf-8')

and decode it like:

decoded_token = jwt.decode(encoded_token, 'secret', algorithms=['HS256'])

@Oxyrus
Copy link
Author

Oxyrus commented Dec 15, 2017

Thanks a lot @vimalloc that solves the issue!

@jpadilla
Copy link
Owner

@vimalloc thank you for helping out, really appreciate it 🥇

@akash1551
Copy link

Thanks @vimalloc , You saved me.

@PauloViniciusBaleeiro
Copy link

Thanks @vimalloc, after spent a whole day in this, i found this issue and, principally, your ask.

ylynfatt added a commit to uwi-info3180/flask-jwt that referenced this issue Mar 18, 2019
@rahul6612
Copy link

This isn't right:

decoded = jwt.decode(token, 'secret', 'utf-8')

You want to create the token like such:

# The decode call here doesn't decode the jwt, it converts the encoded jwt from
# a byte string to a utf-8 string.
data = {'foo': 'bar'}
encoded_token = jwt.encode(data, 'secret', 'HS256').decode('utf-8')

and decode it like:

decoded_token = jwt.decode(encoded_token, 'secret', algorithms=['HS256'])

Thanks a lot @vimalloc that solves the issue!

where we will apply this?

@egor83
Copy link

egor83 commented Jan 15, 2021

Thanks again @vimalloc, and for future googlers, this solves the following exceptions:

binascii.Error: Invalid base64-encoded string: number of data characters (37) cannot be 1 more than a multiple of 4
...
jwt.exceptions.DecodeError: Invalid header padding

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants