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.
Anspruch | Bedeutung | Details |
---|---|---|
iat | Ausgestellt um | Die 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). |
exp | Läuft ab | Dies 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. |
iss | Issuer (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“. |
alg | Nachrichtenauthentifizierungscode-Algorithmus | Dies 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.
#!/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}")
#!/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.
#!/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"
#!/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.
#!/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
#!/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