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) | 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. |
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)://<em>HOSTNAME</em>/api/v3/app" \
--header "Accept: application/vnd.github+json" \
--header "Authorization: Bearer YOUR_JWT"
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.
#!/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}")
#!/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.
#!/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"
#!/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.
#!/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
#!/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