io.jsonwebtoken:jjwt-implnpm install jsonwebtoken axiosconst fs = require('fs');
const jwt = require('jsonwebtoken');
const axios = require('axios');
/**
* Loads a private key from a PEM file
* @param {string} filePath - Path to the PEM file
* @returns {string} Private key as a string
*/
function loadPrivateKeyFromPem(filePath) {
return fs.readFileSync(filePath, 'utf8');
}
/**
* Generates a JWT token with the given app ID and signed using the private key
* @param {number} appId - The application ID to use as issuer
* @param {string} privateKeyPath - Path to the private key PEM file
* @returns {string} Signed JWT token
*/
function generateJwt(appId, privateKeyPath) {
// Load the private key
const privateKey = loadPrivateKeyFromPem(privateKeyPath);
// Get current time in seconds
const nowSeconds = Math.floor(Date.now() / 1000);
// Create the payload
const payload = {
iss: appId.toString(),
iat: nowSeconds,
exp: nowSeconds + 600
};
// Sign the JWT
return jwt.sign(payload, privateKey, { algorithm: 'RS256' });
}
/**
* Exchanges the JWT for an access token
* @param {string} jwtToken - The JWT token to exchange
* @param {number} orgId - The organization ID
* @returns {Promise} Promise resolving to the access token response
*/
async function exchangeJwtForAccessToken(jwtToken, orgId) {
try {
const response = await axios.post(
`https://api.example.com/application/installation/${orgId}/token`,
{ token: jwtToken },
{
headers: {
'Authorization': `Bearer ${jwtToken}`,
'Content-Type': 'application/json'
}
}
);
return response.data;
} catch (error) {
throw error;
}
}
/**
* Makes an API call with the access token in the Authorization header
* @param {string} accessToken - The access token to use for authorization
* @returns {Promise} Promise resolving to the API response
*/
async function makeApiCall(accessToken) {
try {
const response = await axios.get('https://api.example.com/', {
headers: {
'Authorization': `Bearer ${accessToken}`
}
});
return response;
} catch (error) {
throw error;
}
}
/**
* Main function to demonstrate the JWT generation, token exchange, and API call
*/
async function main() {
// Example usage
const appId = 12345;
const orgId = 67890;
const privateKeyPath = 'path/to/private_key.pem';
try {
// Generate JWT
const jwt = generateJwt(appId, privateKeyPath);
console.log('JWT generated successfully');
// Exchange JWT for access token
const tokenResponse = await exchangeJwtForAccessToken(jwt, orgId);
const accessToken = tokenResponse.access_token;
const expiresAt = tokenResponse.expires_at;
console.log(`Access token received, expires at: ${expiresAt}`);
// Make API call with access token
const response = await makeApiCall(accessToken);
// Print response
console.log(`Status code: ${response.status}`);
console.log(`Response body:`, response.data);
} catch (error) {
console.error('Error:', error.message);
if (error.response) {
console.error('Response status:', error.response.status);
console.error('Response data:', error.response.data);
}
}
}
// Execute the main function
main();pip install pyjwt requests cryptographyimport jwt
import time
import requests
from pathlib import Path
from cryptography.hazmat.primitives.serialization import load_pem_private_key
from cryptography.hazmat.backends import default_backend
def load_private_key_from_pem(file_path):
"""
Loads a private key from a PEM file
Args:
file_path (str): Path to the PEM file
Returns:
cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey: The private key object
"""
pem_data = Path(file_path).read_bytes()
# Load the private key - passing None for password if the key is not encrypted
private_key = load_pem_private_key(pem_data, password=None, backend=default_backend())
return private_key
def generate_jwt(app_id, private_key_path):
"""
Generates a JWT token with the given app ID and signed using the private key
Args:
app_id (int): The application ID to use as issuer
private_key_path (str): Path to the private key PEM file
Returns:
str: Signed JWT token
"""
# Load the private key
private_key = load_private_key_from_pem(private_key_path)
# Get current time in seconds
now_seconds = int(time.time())
# Create the payload
payload = {
'iss': str(app_id),
'iat': now_seconds,
'exp': now_seconds + 600
}
# Sign the JWT
return jwt.encode(payload, private_key, algorithm='RS256')
def exchange_jwt_for_access_token(jwt_token, org_id):
"""
Exchanges the JWT for an access token
Args:
jwt_token (str): The JWT token to exchange
org_id (int): The organization ID
Returns:
dict: The access token response containing access_token and expires_at
"""
headers = {
'Authorization': f'Bearer {jwt_token}',
'Content-Type': 'application/json'
}
payload = {
'token': jwt_token
}
response = requests.post(
f'https://api.example.com/application/installation/{org_id}/token',
headers=headers,
json=payload
)
response.raise_for_status() # Raise an exception for HTTP errors
return response.json()
def make_api_call(access_token):
"""
Makes an API call with the access token in the Authorization header
Args:
access_token (str): The access token to use for authorization
Returns:
requests.Response: The API response
"""
headers = {
'Authorization': f'Bearer {access_token}'
}
return requests.get('https://api.example.com/', headers=headers)
def main():
"""
Main function to demonstrate the JWT generation, token exchange, and API call
"""
# Example usage
app_id = 12345
org_id = 67890
private_key_path = 'path/to/private_key.pem'
try:
# Generate JWT
jwt_token = generate_jwt(app_id, private_key_path)
print("JWT generated successfully")
# Exchange JWT for access token
token_response = exchange_jwt_for_access_token(jwt_token, org_id)
access_token = token_response['access_token']
expires_at = token_response['expires_at']
print(f"Access token received, expires at: {expires_at}")
# Make API call with access token
response = make_api_call(access_token)
# Print response
print(f"Status code: {response.status_code}")
print(f"Response body: {response.text}")
except Exception as e:
print(f"Error: {str(e)}")
if __name__ == "__main__":
main()import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.time.Instant;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.jackson.io.JacksonDeserializer;
import io.jsonwebtoken.jackson.io.JacksonSerializer;
import io.jsonwebtoken.io.Deserializer;
import io.jsonwebtoken.io.Serializer;
public class JwtApiClient {
/**
* Generates a JWT token with the given app ID and signed using the private key
*/
public static String generateJwt(int appId, String privateKeyPath) throws Exception {
// Load the private key from the PEM file
PrivateKey privateKey = loadPrivateKeyFromPem(privateKeyPath);
// Get current time
long nowSeconds = Instant.now().getEpochSecond();
// Build the JWT
return Jwts.builder()
.setIssuer(String.valueOf(appId))
.setIssuedAt(new Date(nowSeconds * 1000))
.setExpiration(new Date((nowSeconds + 600) * 1000))
.signWith(privateKey, SignatureAlgorithm.RS256)
.compact();
}
/**
* Exchanges the JWT for an access token
*/
public static Map<String, Object> exchangeJwtForAccessToken(String jwt, int orgId) throws IOException, InterruptedException {
HttpClient client = HttpClient.newHttpClient();
// Create the JSON payload
String jsonPayload = String.format("{\"token\":\"%s\"}", jwt);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/application/installation/" + orgId + "/token"))
.header("Authorization", "Bearer " + jwt)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() >= 400) {
throw new IOException("Failed to exchange token: " + response.statusCode() + ", " + response.body());
}
// Parse the JSON response using the JJWT Jackson deserializer
Deserializer<Map<String, ?>> deserializer = new JacksonDeserializer<>();
return (Map<String, Object>) deserializer.deserialize(response.body().getBytes());
}
/**
* Makes an API call to the root endpoint with the access token in the Authorization header
*/
public static HttpResponse<String> makeApiCall(String accessToken) throws IOException, InterruptedException {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/"))
.header("Authorization", "Bearer " + accessToken)
.GET()
.build();
return client.send(request, HttpResponse.BodyHandlers.ofString());
}
/**
* Loads an RSA private key from a PEM file
*/
private static PrivateKey loadPrivateKeyFromPem(String filePath) throws Exception {
String key = new String(Files.readAllBytes(Paths.get(filePath)));
// Remove PEM format headers and footers and decode
String privateKeyPEM = key
.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replaceAll("\\s", "");
byte[] encoded = Base64.getDecoder().decode(privateKeyPEM);
// Create the private key
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
return keyFactory.generatePrivate(keySpec);
}
public static void main(String[] args) {
// Example usage
int appId = 12345;
int orgId = 67890;
String privateKeyPath = "path/to/private_key.pem";
try {
// 1. Generate JWT
String jwt = generateJwt(appId, privateKeyPath);
System.out.println("JWT generated successfully");
// 2. Exchange JWT for access token
Map<String, Object> tokenResponse = exchangeJwtForAccessToken(jwt, orgId);
String accessToken = (String) tokenResponse.get("access_token");
String expiresAt = (String) tokenResponse.get("expires_at");
System.out.println("Access token received, expires at: " + expiresAt);
// 3. Make API call with access token
HttpResponse<String> response = makeApiCall(accessToken);
// 4. Print response
System.out.println("Status code: " + response.statusCode());
System.out.println("Response body: " + response.body());
} catch (Exception e) {
e.printStackTrace();
}
}
}