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)Die Client-ID oder Anwendungs-ID Ihrer GitHub App. Dieser Wert wird verwendet, um den richtigen öffentlichen Schlüssel zu finden, um die Signatur der JWT-Methode zu überprüfen. Du findest die ID deiner Apps auf der Einstellungsseite für deine GitHub App. Die Verwendung der Client-ID wird empfohlen. Weitere Informationen zur Navigation zur Einstellungsseite für deine GitHub App findest du unter „Ändern einer GitHub-App-Registrierung“.
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 "http(s)://HOSTNAME/api/v3/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 client ID
  iss: "YOUR_CLIENT_ID"
}

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

Beispiel: Verwenden von Python zum Generieren eines JWT

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

Python
#!/usr/bin/env python3
import sys
import time

import jwt

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

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

# Open PEM
with open(pem, 'rb') as pem_file:
    signing_key = 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 client ID
    'iss': client_id
}

# Create JWT
encoded_jwt = jwt.encode(payload, signing_key, algorithm='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 Client-ID und den Dateipfad übergeben, in dem dein privater Schlüssel beim Ausführen dieses Skripts als Argument gespeichert wird.

Bash
#!/usr/bin/env bash

set -o pipefail

client_id=$1 # Client 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\":\"${client_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_CLIENT_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

$client_id = YOUR_CLIENT_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 = $client_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