Skip to main content

HTTP / cURL Reference

Pure HTTP examples for integrating ConsentKeys into any language or platform. Use these cURL commands to test and understand the OAuth flow.

Prerequisites

Get your Client ID and Secret from the Developer Portal and configure your redirect URI (where users return to your app after authentication).

Quick Start

The complete OAuth 2.0 Authorization Code flow with PKCE:

# 1. Generate PKCE parameters
CODE_VERIFIER=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-43)
CODE_CHALLENGE=$(echo -n "$CODE_VERIFIER" | openssl dgst -binary -sha256 | base64 | tr -d "=+/" | tr '/+' '_-')
STATE=$(openssl rand -hex 16)

# 2. Build authorization URL (open in browser)
CLIENT_ID="ck_your_client_id"
REDIRECT_URI="http://localhost:3000/callback" # Must match what you configured
AUTH_URL="https://pseudoidc.consentkeys.com/auth?response_type=code&client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI&scope=openid%20profile%20email&state=$STATE&code_challenge=$CODE_CHALLENGE&code_challenge_method=S256"

echo "Open this URL in your browser:"
echo "$AUTH_URL"

# 3. After authentication, you'll be redirected to:
# http://localhost:3000/callback?code=AUTH_CODE&state=STATE

# 4. Exchange code for tokens
AUTH_CODE="paste_code_from_redirect"
CLIENT_SECRET="your_client_secret"

curl -X POST https://pseudoidc.consentkeys.com/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=$AUTH_CODE" \
-d "redirect_uri=$REDIRECT_URI" \
-d "client_id=$CLIENT_ID" \
-d "client_secret=$CLIENT_SECRET" \
-d "code_verifier=$CODE_VERIFIER"

# 5. Get user info
ACCESS_TOKEN="paste_access_token_from_response"

curl https://pseudoidc.consentkeys.com/userinfo \
-H "Authorization: Bearer $ACCESS_TOKEN"

OIDC Discovery

Get OpenID Connect configuration:

curl https://pseudoidc.consentkeys.com/.well-known/openid-configuration

Response:

{
"issuer": "https://pseudoidc.consentkeys.com",
"authorization_endpoint": "https://pseudoidc.consentkeys.com/auth",
"token_endpoint": "https://pseudoidc.consentkeys.com/token",
"userinfo_endpoint": "https://pseudoidc.consentkeys.com/userinfo",
"jwks_uri": "https://pseudoidc.consentkeys.com/.well-known/jwks.json",
"introspection_endpoint": "https://pseudoidc.consentkeys.com/introspect",
"revocation_endpoint": "https://pseudoidc.consentkeys.com/revoke",
"response_types_supported": ["code"],
"subject_types_supported": ["public"],
"id_token_signing_alg_values_supported": ["RS256"],
"scopes_supported": ["openid", "profile", "email", "address"],
"grant_types_supported": ["authorization_code"],
"code_challenge_methods_supported": ["S256", "plain"]
}

:::info[Important Notes]
- **Grant Types**: The backend fully implements `client_credentials` flow but the discovery endpoint currently only advertises `authorization_code`. If you need machine-to-machine authentication, `client_credentials` is supported.
- **PKCE Methods**: Both `S256` (SHA-256) and `plain` are supported. **Use `S256` in production** for better security. The `plain` method should only be used in constrained environments.
:::

Get JWKS

Public keys for token verification:

curl https://pseudoidc.consentkeys.com/.well-known/jwks.json

Response:

{
"keys": [
{
"kty": "RSA",
"use": "sig",
"kid": "key-2024",
"n": "...",
"e": "AQAB",
"alg": "RS256"
}
]
}

Authorization Flow

Step 1: Generate PKCE Challenge

Bash:

# Generate code verifier (random 43-char string)
CODE_VERIFIER=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-43)

# Generate code challenge (SHA-256 hash of verifier)
CODE_CHALLENGE=$(echo -n "$CODE_VERIFIER" | openssl dgst -binary -sha256 | base64 | tr -d "=+/" | tr '/+' '_-')

# Generate state for CSRF protection
STATE=$(openssl rand -hex 16)

echo "Code Verifier: $CODE_VERIFIER"
echo "Code Challenge: $CODE_CHALLENGE"
echo "State: $STATE"

Python:

import secrets
import hashlib
import base64

# Generate code verifier
code_verifier = base64.urlsafe_b64encode(secrets.token_bytes(32)).decode('utf-8').rstrip('=')

# Generate code challenge
digest = hashlib.sha256(code_verifier.encode('utf-8')).digest()
code_challenge = base64.urlsafe_b64encode(digest).decode('utf-8').rstrip('=')

# Generate state
state = secrets.token_urlsafe(16)

print(f"Code Verifier: {code_verifier}")
print(f"Code Challenge: {code_challenge}")
print(f"State: {state}")

JavaScript:

// Generate code verifier
function generateCodeVerifier() {
const array = new Uint8Array(32);
crypto.getRandomValues(array);
return base64UrlEncode(array);
}

// Generate code challenge
async function generateCodeChallenge(verifier) {
const encoder = new TextEncoder();
const data = encoder.encode(verifier);
const hash = await crypto.subtle.digest('SHA-256', data);
return base64UrlEncode(new Uint8Array(hash));
}

function base64UrlEncode(array) {
return btoa(String.fromCharCode(...array))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}

// Generate state
function generateState() {
return generateCodeVerifier().substring(0, 16);
}

Step 2: Authorization Request

Request:

GET /auth?response_type=code&client_id=ck_abc123&redirect_uri=http://localhost:3000/callback&scope=openid%20profile%20email&state=xyz789&code_challenge=CHALLENGE&code_challenge_method=S256 HTTP/1.1
Host: pseudoidc.consentkeys.com

cURL:

# This opens in a browser - construct the URL:
CLIENT_ID="ck_your_client_id"
REDIRECT_URI="https://pseudoidc.consentkeys.com/callback"
SCOPE="openid profile email"
STATE="your_random_state"
CODE_CHALLENGE="your_code_challenge"

# Open this URL in browser
echo "https://pseudoidc.consentkeys.com/auth?\
response_type=code&\
client_id=$CLIENT_ID&\
redirect_uri=$REDIRECT_URI&\
scope=$SCOPE&\
state=$STATE&\
code_challenge=$CODE_CHALLENGE&\
code_challenge_method=S256"

Response:

User will be redirected to:

https://pseudoidc.consentkeys.com/callback?code=AUTH_CODE_HERE&state=xyz789

Step 3: Token Exchange

Request:

POST /token HTTP/1.1
Host: pseudoidc.consentkeys.com
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&
code=AUTH_CODE_HERE&
redirect_uri=http://localhost:3000/callback&
client_id=ck_abc123&
client_secret=SECRET_HERE&
code_verifier=CODE_VERIFIER_HERE

cURL:

curl -X POST https://pseudoidc.consentkeys.com/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=AUTH_CODE" \
-d "redirect_uri=http://localhost:3000/callback" \
-d "client_id=ck_your_client_id" \
-d "client_secret=your_secret" \
-d "code_verifier=$CODE_VERIFIER"

Response:

{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600,
"id_token": "eyJhbGciOiJSUzI1NiIs...",
"scope": "openid profile email"
}

Step 4: Get User Info

Request:

GET /userinfo HTTP/1.1
Host: pseudoidc.consentkeys.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...

cURL:

curl https://pseudoidc.consentkeys.com/userinfo \
-H "Authorization: Bearer $ACCESS_TOKEN"

Response:

{
"sub": "user_123abc",
"email": "user@example.com",
"email_verified": true,
"name": "John Doe",
"preferred_username": "johnd",
"picture": "https://cdn.consentkeys.com/avatars/..."
}

Token Introspection

Check if a token is valid:

Request:

POST /introspect HTTP/1.1
Host: pseudoidc.consentkeys.com
Content-Type: application/x-www-form-urlencoded

token=eyJhbGciOiJSUzI1NiIs...&
client_id=ck_abc123&
client_secret=SECRET_HERE

cURL:

curl -X POST https://pseudoidc.consentkeys.com/introspect \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "token=$ACCESS_TOKEN" \
-d "client_id=$CLIENT_ID" \
-d "client_secret=$CLIENT_SECRET"

Response:

{
"active": true,
"sub": "user_123abc",
"client_id": "ck_abc123",
"exp": 1703980800,
"iat": 1703977200,
"iss": "https://pseudoidc.consentkeys.com",
"scope": "openid profile email",
"token_type": "Bearer"
}

Token Revocation

Revoke an access token:

Request:

POST /revoke HTTP/1.1
Host: pseudoidc.consentkeys.com
Content-Type: application/x-www-form-urlencoded

token=eyJhbGciOiJSUzI1NiIs...&
client_id=ck_abc123&
client_secret=SECRET_HERE

cURL:

curl -X POST https://pseudoidc.consentkeys.com/revoke \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "token=$ACCESS_TOKEN" \
-d "client_id=$CLIENT_ID" \
-d "client_secret=$CLIENT_SECRET"

Response:

HTTP/1.1 200 OK

Client Credentials Flow

For machine-to-machine authentication:

Request:

POST /token HTTP/1.1
Host: pseudoidc.consentkeys.com
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&
client_id=ck_abc123&
client_secret=SECRET_HERE&
scope=openid

cURL:

curl -X POST https://pseudoidc.consentkeys.com/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=$CLIENT_ID" \
-d "client_secret=$CLIENT_SECRET" \
-d "scope=openid"

Response:

{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "openid"
}

Error Responses

All endpoints return OAuth 2.0 error format:

{
"error": "invalid_request",
"error_description": "The redirect_uri parameter is required"
}

Common errors:

ErrorDescription
invalid_requestMissing required parameter
invalid_clientInvalid client credentials
invalid_grantAuthorization code expired/invalid
unauthorized_clientClient not authorized for this action
access_deniedUser denied authorization
invalid_scopeRequested scope not supported
server_errorInternal server error
too_many_requestsRate limit exceeded

Complete Shell Script

oauth_flow.sh
#!/bin/bash

# Configuration
CLIENT_ID="ck_your_client_id"
CLIENT_SECRET="your_client_secret"
REDIRECT_URI="https://pseudoidc.consentkeys.com/callback"
BASE_URL="https://pseudoidc.consentkeys.com"

# Generate PKCE
CODE_VERIFIER=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-43)
CODE_CHALLENGE=$(echo -n "$CODE_VERIFIER" | openssl dgst -binary -sha256 | base64 | tr -d "=+/" | tr '/+' '_-')
STATE=$(openssl rand -hex 16)

# Build auth URL
AUTH_URL="$BASE_URL/auth?response_type=code&client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI&scope=openid%20profile%20email&state=$STATE&code_challenge=$CODE_CHALLENGE&code_challenge_method=S256"

echo "1. Open this URL in your browser:"
echo "$AUTH_URL"
echo ""
echo "2. After authentication, paste the 'code' parameter from the redirect URL:"
read -r AUTH_CODE

echo ""
echo "3. Exchanging code for tokens..."

# Exchange code for tokens
TOKEN_RESPONSE=$(curl -s -X POST "$BASE_URL/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=$AUTH_CODE" \
-d "redirect_uri=$REDIRECT_URI" \
-d "client_id=$CLIENT_ID" \
-d "client_secret=$CLIENT_SECRET" \
-d "code_verifier=$CODE_VERIFIER")

echo "$TOKEN_RESPONSE" | jq '.'

# Extract access token
ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.access_token')

echo ""
echo "4. Getting user info..."

# Get user info
curl -s "$BASE_URL/userinfo" \
-H "Authorization: Bearer $ACCESS_TOKEN" | jq '.'

Language Examples

Go

package main

import (
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"fmt"
"net/http"
"net/url"
)

func generatePKCE() (string, string) {
// Generate verifier
b := make([]byte, 32)
rand.Read(b)
verifier := base64.RawURLEncoding.EncodeToString(b)

// Generate challenge
h := sha256.New()
h.Write([]byte(verifier))
challenge := base64.RawURLEncoding.EncodeToString(h.Sum(nil))

return verifier, challenge
}

func main() {
verifier, challenge := generatePKCE()

params := url.Values{}
params.Add("response_type", "code")
params.Add("client_id", "ck_your_client_id")
params.Add("redirect_uri", "https://pseudoidc.consentkeys.com/callback")
params.Add("scope", "openid profile email")
params.Add("code_challenge", challenge)
params.Add("code_challenge_method", "S256")

authURL := "https://pseudoidc.consentkeys.com/auth?" + params.Encode()
fmt.Println(authURL)
}

Ruby

require 'securerandom'
require 'digest'
require 'base64'
require 'uri'
require 'net/http'
require 'json'

# Generate PKCE
code_verifier = Base64.urlsafe_encode64(SecureRandom.random_bytes(32), padding: false)
code_challenge = Base64.urlsafe_encode64(Digest::SHA256.digest(code_verifier), padding: false)

# Build auth URL
params = {
response_type: 'code',
client_id: 'ck_your_client_id',
redirect_uri: 'https://pseudoidc.consentkeys.com/callback',
scope: 'openid profile email',
code_challenge: code_challenge,
code_challenge_method: 'S256'
}

auth_url = "https://pseudoidc.consentkeys.com/auth?#{URI.encode_www_form(params)}"
puts auth_url

PHP

<?php

function generateCodeVerifier() {
return rtrim(strtr(base64_encode(random_bytes(32)), '+/', '-_'), '=');
}

function generateCodeChallenge($verifier) {
return rtrim(strtr(base64_encode(hash('sha256', $verifier, true)), '+/', '-_'), '=');
}

$codeVerifier = generateCodeVerifier();
$codeChallenge = generateCodeChallenge($codeVerifier);

$params = http_build_query([
'response_type' => 'code',
'client_id' => 'ck_your_client_id',
'redirect_uri' => 'https://pseudoidc.consentkeys.com/callback',
'scope' => 'openid profile email',
'code_challenge' => $codeChallenge,
'code_challenge_method' => 'S256',
]);

$authUrl = "https://pseudoidc.consentkeys.com/auth?{$params}";
echo $authUrl;
?>

Next Steps