Generating admin API tokens in Python

Hi there,

I’m trying to generate the correct API token for the admin API using python, but for some reason it just won’t accept what I generate. Maybe someone here can tell me what I did wrong, or show me some code that actually works?

I’ve validated my API key with the Ruby reference code on the API documentation, and I’ve validated the remainder of my code using a token generated by that Ruby code.

def generate_token(key):
    kid, secret = key.split(':')
    iat = datetime.datetime.utcnow()
    exp = datetime.datetime.utcnow() + datetime.timedelta(seconds=300)
    header = {
        'kid': kid
    }
    payload = {
        'iat': iat,
        'exp': exp,
        'aud': '/v2/admin/'
    }

    return jwt.encode(payload, secret, algorithm='HS256', headers=header).decode('utf-8')

Your help is immensely appreciated. I run a self-hosted ghost blog running latest 2.x release.

This piece of code in the ruby example [secret].pack('H*') is converting the hex representation of the secret back into raw bytes/binary, does your jwt.encode handle that for you or do you need to add that step into your script?

The same step is done in the JS example Buffer.from(secret, 'hex') and in the Bash example an option is passed to openssl to indicate the secret is in hex and needs converting hexkey:$SECRET

I was sure I had tested that, but you’re absolutely right. It was indeed the binary encoding that was wrong.

Here is the working code:

def generate_token(key):
    kid, secret = key.split(':')
    bsecret = bytes.fromhex(secret)
    iat = datetime.datetime.utcnow()
    exp = datetime.datetime.utcnow() + datetime.timedelta(seconds=300)
    header = {
        'kid': kid
    }
    payload = {
        'iat': iat,
        'exp': exp,
        'aud': '/v2/admin/'
    }

    return jwt.encode(payload, bsecret, algorithm='HS256', headers=header).decode('utf-8')
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.