0

I'm suffering from verify_id_token() error with (google) firebase admin-sdk in auth module.

When I verify the user by user's token posted by frontend js, auth.verify_id_token(token) method arise "binascii.Error: Incorrect padding" error.

Traceback of this error is below.

Traceback (most recent call last):
  File "/home/ubuntu/.pyenv/versions/3.6.2/lib/python3.6/site-packages/flask/app.py", line 1997, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/ubuntu/.pyenv/versions/3.6.2/lib/python3.6/site-packages/flask/app.py", line 1985, in wsgi_app
    response = self.handle_exception(e)
  File "/home/ubuntu/.pyenv/versions/3.6.2/lib/python3.6/site-packages/flask/app.py", line 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/ubuntu/.pyenv/versions/3.6.2/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/home/ubuntu/.pyenv/versions/3.6.2/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/ubuntu/.pyenv/versions/3.6.2/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/ubuntu/.pyenv/versions/3.6.2/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/ubuntu/.pyenv/versions/3.6.2/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/home/ubuntu/.pyenv/versions/3.6.2/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/ubuntu/.pyenv/versions/3.6.2/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/ubuntu/workdir/server/firebase.py", line 185, in postme
    decoded_token = auth.verify_id_token(posted)
  File "/home/ubuntu/.pyenv/versions/3.6.2/lib/python3.6/site-packages/firebase_admin/auth.py", line 98, in verify_id_token
    return token_generator.verify_id_token(id_token)
  File "/home/ubuntu/.pyenv/versions/3.6.2/lib/python3.6/site-packages/firebase_admin/auth.py", line 592, in verify_id_token
    header = jwt.decode_header(id_token)
  File "/home/ubuntu/.pyenv/versions/3.6.2/lib/python3.6/site-packages/google/auth/jwt.py", line 151, in decode_header
    header, _, _, _ = _unverified_decode(token)
  File "/home/ubuntu/.pyenv/versions/3.6.2/lib/python3.6/site-packages/google/auth/jwt.py", line 129, in _unverified_decode
    signature = _helpers.padded_urlsafe_b64decode(signature)
  File "/home/ubuntu/.pyenv/versions/3.6.2/lib/python3.6/site-packages/google/auth/_helpers.py", line 217, in padded_urlsafe_b64decode
    return base64.urlsafe_b64decode(padded)
  File "/home/ubuntu/.pyenv/versions/3.6.2/lib/python3.6/base64.py", line 133, in urlsafe_b64decode
    return b64decode(s)
  File "/home/ubuntu/.pyenv/versions/3.6.2/lib/python3.6/base64.py", line 87, in b64decode
    return binascii.a2b_base64(s)
binascii.Error: Incorrect padding

I posted the client token by javascript from client like below.

        var token = user.getIdToken()
        var bapi = axios.create({
          baseURL: 'http://mypage.com',
          timeout: 10000,
          headers: {
            'X-Requested-With': 'XMLHttpRequest'
          }
        })

        bapi.post('/postme', token)
        .then(response => {
          console.log(response)
        }).catch(err => {
          console.log(err)
        })

And decode it by python(flask) at requested server

@app.route('/postme',methods=['POST'])
def postme():
    posted = request.data
    decoded_token = auth.verify_id_token(posted) # error!!

    # uid = decoded_token['uid']
    return uid

Does anyone know what to do??

KENdi
  • 7,576
  • 2
  • 16
  • 31
tom__bo
  • 11
  • 6

2 Answers2

1

In the JavaScript SDK, user.getIdToken() is implemented as an asynchronous function (documentation), but your code assumes that it returns a String directly.

Therefore your backend is receiving garbage – which you could have noticed if you printed the contents of the posted variable.


Reorganize the JS function like this to actually use the ID token:

user.getIdToken()
    .then(token => {
        var bapi = axios.create({
            baseURL: 'http://mypage.com',
            timeout: 10000,
            headers: {'X-Requested-With': 'XMLHttpRequest'}
        });

        return bapi.post('/postme', token);
    })
    .then(response => {
      console.log(response)
    }).catch(err => {
      console.log(err)
    })
vzsg
  • 2,831
  • 17
  • 20
  • I didn't know that user.getIdToken() return promise, and I try what you said. But when I tried ```bapi.post('/postme', token);``` in js side, python server received empty string (b''). – tom__bo Sep 18 '17 at 14:21
  • ```bapi.post('/postme', {token});``` looks good, because python server received ```b'{"token":"...(encoded string)..."}'``` which can be confirmed by jwt.io. But same error is arised. – tom__bo Sep 18 '17 at 14:24
1

Finally, this problem was solved thanks to @vzsg(thank you so much again).

In conclusion,

  • user.getIdToken() in firebase SDK (js) returns promise
  • auth.verify_id_token(token) in firebase admin-sdk (python) needs only encoded string.
tom__bo
  • 11
  • 6