Skip to content

Instantly share code, notes, and snippets.

@thameera
Created September 16, 2025 05:05
Show Gist options
  • Save thameera/c4b6c170a023b710ce0793329af7a26b to your computer and use it in GitHub Desktop.
Save thameera/c4b6c170a023b710ce0793329af7a26b to your computer and use it in GitHub Desktop.
Auth0 Device Flow

Auth0 Device Flow tester

This flow lets you try out the Auth0 Device Flow using a CLI.

Update the parameters AUTH0_DOMAIN, CLIENT_ID, and AUDIENCE at the top of the file first.

Run node index.js to try the flow.

const { exec } = require('child_process');
const readline = require('readline');
const AUTH0_DOMAIN = 'TENANT_DOMAIN';
const CLIENT_ID = 'CLIENT_ID';
const AUDIENCE = 'AUDIENCE';
const DEVICE_CODE_URL = `https://${AUTH0_DOMAIN}/oauth/device/code`;
const TOKEN_URL = `https://${AUTH0_DOMAIN}/oauth/token`;
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function pollForToken(deviceCode, intervalSeconds) {
const body = {
grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
device_code: deviceCode,
client_id: CLIENT_ID,
};
let interval = Number(intervalSeconds) || 5;
while (true) {
// wait interval seconds before each poll
await sleep(interval * 1000);
let response;
let data;
try {
console.log(`Polling token endpoint (interval ${interval} seconds)...`);
response = await fetch(TOKEN_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
data = await response.json();
} catch (err) {
throw new Error('Network error while polling token endpoint: ' + err.message);
}
if (response.ok) {
// Success — return token response
return data;
}
// Not OK — handle known device flow errors
const errCode = data && data.error;
if (errCode === 'authorization_pending') {
console.log("Authorization is pending.");
// keep polling
continue;
}
if (errCode === 'access_denied') {
throw new Error('Access denied by user: ' + (data.error_description || ''));
}
if (errCode === 'slow_down') {
// increase interval per spec
interval += 5;
continue;
}
// Unknown error — throw
throw new Error('Token endpoint error: ' + JSON.stringify(data));
}
}
const getDeviceCode = async () => {
console.log(`Sending request to: ${DEVICE_CODE_URL}`);
const body = {
client_id: CLIENT_ID,
scope: 'openid profile email',
audience: AUDIENCE,
};
try {
const response = await fetch(DEVICE_CODE_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
const responseData = await response.json();
if (!response.ok) {
const errorMessage = responseData.error_description || `HTTP error! Status: ${response.status}`;
throw new Error(errorMessage);
}
return responseData;
} catch (error) {
console.error('An error occurred during the fetch operation:', error);
throw error;
}
}
async function main() {
try {
const deviceCodeResponse = await getDeviceCode();
console.log('\nReceived response from Auth0:');
console.log(JSON.stringify(deviceCodeResponse, null, 2));
const verificationUrl = deviceCodeResponse.verification_uri_complete;
if (!verificationUrl) {
console.warn('\nERROR: No verification URL found in the response.');
process.exit(1);
}
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
console.log(`\nPress Enter to open the verification URL in your browser:\n${verificationUrl}`);
// wait for user to press Enter
const questionAsync = (query = '') => new Promise((resolve) => rl.question(query, resolve));
await questionAsync('');
console.log('Opening browser...');
exec('open ' + verificationUrl, (err) => {
if (err) {
console.error('Failed to open browser:', err);
} else {
console.log('Browser opened. Follow the instructions to complete sign-in.');
}
});
// Start polling for tokens
const tokens = await pollForToken(deviceCodeResponse.device_code, deviceCodeResponse.interval);
console.log('\nToken response received:');
console.log(JSON.stringify(tokens, null, 2));
} catch (error) {
console.error('\nScript finished with an error.');
console.error('Error details:', error);
process.exit(1);
}
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment