teilin / dotnetghost

Dotnet Ghost is a library that helps connecting to the Ghost API. Both the content api and the admin api.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Generate JWT token

teilin opened this issue · comments

Generate a JWT token that is used to communicate with the Ghost Admin API.

Admin API keys are made up of an id and secret, separated by a colon. These values are used separately to get a signed JWT token, which is used in the Authorization header of the request:

curl -H "Authorization: Ghost $token" https://{admin_domain}/ghost/api/{version}/admin/{resource}/

Token Generation

JSON Web Tokens are made up of a header, a payload and a secret. The values needed for the header and payload are:

Header:

{
    "alg": "HS256",
    "kid": {id}, // ID from your API key
    "typ": "JWT"
}

Payload:

{
    // Timestamps are seconds sine the unix epoch, not milliseconds
    "exp": {timestamp}, // Max 5 minutes after 'now'
    "iat": {timestamp}, // 'now' (max 5 minutes after 'exp')
    "aud": "/{version}/admin/"
}

The libraries on https://jwt.io all work slightly differently, but all of them allow you to specify the above required values, including setting the signing algorithm to the required HS-256. Where possible, the API will provide specific error messages when required values are missing or incorrect.

Regardless of language, you'll need to:

  • Split the API key by the : into an id and a secret
  • Decode the hexadecimal secret into the original binary byte array
  • Pass these values to your JWT library of choice, ensuring that the header and payload are correct.

Below is a Python script that generate a valid token:

import requests # pip install requests
import jwt  # pip install pyjwt
from datetime import datetime as date

# Admin API key goes here
key = '<id>:<secretid>'

# Split the key into ID and SECRET
id, secret = key.split(':')

# Prepare header and payload
iat = int(date.now().timestamp())

header = {'alg': 'HS256', 'typ': 'JWT', 'kid': id}
payload = {
    'iat': iat,
    'exp': iat + 5 * 60,
    'aud': '/v3/admin/'
}

# Create the token (including decoding secret)
token = jwt.encode(payload, bytes.fromhex(secret), algorithm='HS256', headers=header)

print(token.decode())

More information at the Ghost documentation.