Skip to main content

Generieren eines JSON Web Token (JWT) für eine GitHub-App

Hier erfährst du, wie du ein JSON Web Token (JWT) erstellst, um dich mit deiner GitHub App bei bestimmten REST-API-Endpunkten zu authentifizieren.

Informationen zu JSON Web Token (JWTs)

Zur Authentifizierung als App oder zum Generieren eines Installationszugriffstokens musst du ein JSON Web Token (JWT) generieren. Wenn ein REST-API-Endpunkt ein JWT erfordert, wird in der Dokumentation für den jeweiligen Endpunkt angegeben, dass für den Zugriff ein JWT erforderlich ist.

Dein JWT muss mit dem RS256-Algorithmus signiert sein und die folgenden Ansprüche enthalten.

AnspruchBedeutungDetails
iatAusgestellt umDie Zeitpunkt, zu dem die JWT-Instanz erstellt wurde. Zum Schutz vor Uhrenfehlern solltest du diese 60 Sekunden in der Vergangenheit festlegen und sicherstellen, dass Datum und Uhrzeit deines Servers genau eingestellt sind (z. B. mithilfe des Network Time Protocol).
expLäuft abDies ist die Ablaufzeit der JWT-Methode, nach der sie nicht mehr zum Anfordern eines Installationstokens verwendet werden kann. Der Zeitpunkt darf nicht später als 10 Minuten in der Zukunft liegen.
issIssuer (Aussteller)Dies ist die ID deiner GitHub App. Dieser Wert wird verwendet, um den richtigen öffentlichen Schlüssel zu finden, um die Signatur der JWT-Methode zu überprüfen. Du kannst die ID deiner App mit dem GET /app REST-API-Endpunkt ermitteln. Weitere Informationen findest du in der REST-API-Dokumentation unter Apps.
algNachrichtenauthentifizierungscode-AlgorithmusDies sollte RS256 sein, da deine JWT-Instanz mit dem RS256-Algorithmus signiert werden muss.

Um ein JWT zu verwenden, übergib es im Authorization-Header einer API-Anforderung. Beispiel:

curl --request GET \
--url "https://api.github.com/app" \
--header "Accept: application/vnd.github+json" \
--header "Authorization: Bearer YOUR_JWT" \
--header "X-GitHub-Api-Version: 2022-11-28"

In den meisten Fällen kannst du Authorization: Bearer oder Authorization: token verwenden, um ein Token zu übergeben. Wenn du jedoch ein JWT (JSON Web Token) übergibst, musst du Authorization: Bearer verwenden.

Generieren von JSON Web Token (JWT)

Die meisten Programmiersprachen verfügen über ein Paket, das ein JWT generieren kann. In allen Fällen benötigst du einen privaten Schlüssel und die ID deiner GitHub App. Weitere Informationen zum Generieren eines privaten Schlüssels findest du unter Verwalten privater Schlüssel für GitHub-Apps. Du kannst die ID deiner App mit dem GET /app REST-API-Endpunkt ermitteln. Weitere Informationen findest du in der REST-API-Dokumentation unter Apps.

Hinweis: Anstatt ein JWT zu erstellen, kannst du die Octokit-SDKs von GitHub verwenden, um dich als App zu authentifizieren. Das SDK kümmert sich um die Generierung eines JWT für dich und generiert das JWT, sobald das Token abläuft. Weitere Informationen findest du unter Skripterstellung mit der REST-API und JavaScript.

Beispiel: Verwenden von Ruby zum Generieren eines JWT

Hinweis: Du musst gem install jwt ausführen, um das jwt-Paket zu installieren, damit du dieses Skript verwenden kannst.

Ersetze im folgenden Beispiel YOUR_PATH_TO_PEM durch den Dateipfad, in dem dein privater Schlüssel gespeichert ist. Ersetze YOUR_APP_ID durch die ID deiner App. Achte darauf, dass die Werte für YOUR_PATH_TO_PEM und YOUR_APP_ID in doppelte Anführungszeichen eingeschlossen werden.

require 'openssl'
require 'jwt'  # https://rubygems.org/gems/jwt

# Private key contents
private_pem = File.read("YOUR_PATH_TO_PEM")
private_key = OpenSSL::PKey::RSA.new(private_pem)

# Generate the JWT
payload = {
  # issued at time, 60 seconds in the past to allow for clock drift
  iat: Time.now.to_i - 60,
  # JWT expiration time (10 minute maximum)
  exp: Time.now.to_i + (10 * 60),
  # GitHub App's identifier
  iss: "YOUR_APP_ID"
}

jwt = JWT.encode(payload, private_key, "RS256")
puts jwt

Beispiel: Verwenden von Python zum Generieren eines JWT

Hinweis: Du musst pip install jwt ausführen, um das jwt-Paket zu installieren, damit du dieses Skript verwenden kannst.

Python
#!/usr/bin/env python3
from jwt import JWT, jwk_from_pem
import time
import sys

# Get PEM file path
if len(sys.argv) > 1:
    pem = sys.argv[1]
else:
    pem = input("Enter path of private PEM file: ")

# Get the App ID
if len(sys.argv) > 2:
    app_id = sys.argv[2]
else:
    app_id = input("Enter your APP ID: ")

# Open PEM
with open(pem, 'rb') as pem_file:
    signing_key = jwk_from_pem(pem_file.read())

payload = {
    # Issued at time
    'iat': int(time.time()),
    # JWT expiration time (10 minutes maximum)
    'exp': int(time.time()) + 600,
    # GitHub App's identifier
    'iss': app_id
}

# Create JWT
jwt_instance = JWT()
encoded_jwt = jwt_instance.encode(payload, signing_key, alg='RS256')

print(f"JWT:  {encoded_jwt}")

Dieses Skript fragt dich nach dem Dateipfad, in dem dein privater Schlüssel gespeichert ist, und der ID deiner App. Alternativ kannst du diese Werte als Inlineargumente übergeben, wenn du das Skript ausführst.

Beispiel: Verwenden von Bash zum Generieren eines JWT

Hinweis: Du musst deine App-ID und den Dateipfad übergeben, in dem dein privater Schlüssel beim Ausführen dieses Skripts als Argumente gespeichert wird.

Bash
#!/usr/bin/env bash

set -o pipefail

app_id=$1 # App ID as first argument
pem=$( cat $2 ) # file path of the private key as second argument

now=$(date +%s)
iat=$((${now} - 60)) # Issues 60 seconds in the past
exp=$((${now} + 600)) # Expires 10 minutes in the future

b64enc() { openssl base64 | tr -d '=' | tr '/+' '_-' | tr -d '\n'; }

header_json='{
    "typ":"JWT",
    "alg":"RS256"
}'
# Header encode
header=$( echo -n "${header_json}" | b64enc )

payload_json='{
    "iat":'"${iat}"',
    "exp":'"${exp}"',
    "iss":'"${app_id}"'
}'
# Payload encode
payload=$( echo -n "${payload_json}" | b64enc )

# Signature
header_payload="${header}"."${payload}"
signature=$( 
    openssl dgst -sha256 -sign <(echo -n "${pem}") \
    <(echo -n "${header_payload}") | b64enc 
)

# Create JWT
JWT="${header_payload}"."${signature}"
printf '%s\n' "JWT: $JWT"

Beispiel: Verwenden von PowerShell zum Generieren eines JWT

Ersetze im folgenden Beispiel YOUR_PATH_TO_PEM durch den Dateipfad, in dem dein privater Schlüssel gespeichert ist. Ersetze YOUR_APP_ID durch die ID deiner App. Achten Sie darauf, dass die Werte für YOUR_PATH_TO_PEM in doppelte Anführungszeichen eingeschlossen werden.

PowerShell
#!/usr/bin/env pwsh

$app_id = YOUR_APP_ID
$private_key_path = "YOUR_PATH_TO_PEM"

$header = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json -InputObject @{
  alg = "RS256"
  typ = "JWT"
}))).TrimEnd('=').Replace('+', '-').Replace('/', '_');

$payload = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json -InputObject @{
  iat = [System.DateTimeOffset]::UtcNow.AddSeconds(-10).ToUnixTimeSeconds()  
  exp = [System.DateTimeOffset]::UtcNow.AddMinutes(10).ToUnixTimeSeconds()
  iss = $app_id    
}))).TrimEnd('=').Replace('+', '-').Replace('/', '_');

$rsa = [System.Security.Cryptography.RSA]::Create()
$rsa.ImportFromPem((Get-Content $private_key_path -Raw))

$signature = [Convert]::ToBase64String($rsa.SignData([System.Text.Encoding]::UTF8.GetBytes("$header.$payload"), [System.Security.Cryptography.HashAlgorithmName]::SHA256, [System.Security.Cryptography.RSASignaturePadding]::Pkcs1)).TrimEnd('=').Replace('+', '-').Replace('/', '_')
$jwt = "$header.$payload.$signature"
Write-Host $jwt