Skip to main content

OAuth Authentication

At a glance

Ontologie supports the OAuth2 protocol with PKCE (Proof Key for Code Exchange) for applications that require authentication on behalf of a user. This flow is recommended for frontend and mobile applications.

When to use OAuth?

MethodUse case
API KeyScripts, automations, server-to-server integrations
OAuth2 PKCEFrontend applications, mobile applications, integrations that act on behalf of a user

OAuth is required when:

  • Your application needs to access a specific user's data
  • You cannot store a secret on the client side (frontend application)
  • You want the user to explicitly authorize access

OAuth2 PKCE flow

Step 1: Generate the code verifier and challenge

Your application generates a random code_verifier and computes the corresponding code_challenge:

// Generer un code verifier aleatoire
function generateCodeVerifier(): string {
const array = new Uint8Array(32);
crypto.getRandomValues(array);
return btoa(String.fromCharCode(...array))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
}

// Calculer le code challenge (SHA-256)
async function generateCodeChallenge(verifier: string): Promise<string> {
const encoder = new TextEncoder();
const data = encoder.encode(verifier);
const hash = await crypto.subtle.digest('SHA-256', data);
return btoa(String.fromCharCode(...new Uint8Array(hash)))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
}

Step 2: Redirect the user

Redirect the user to the authorization page:

https://auth.ontologie-growthsystemes.com/authorize?
response_type=code
&client_id=VOTRE_CLIENT_ID
&redirect_uri=https://votre-app.com/callback
&scope=read:nodes write:nodes
&code_challenge=CODE_CHALLENGE
&code_challenge_method=S256
&state=RANDOM_STATE
ParameterDescription
client_idYour application identifier (obtained during registration)
redirect_uriReturn URL after authorization (must match the registered one)
scopeRequested permissions, separated by spaces
code_challengeSHA-256 hash of the code verifier
stateRandom value to protect against CSRF attacks

Step 3: Exchange the code for a token

After authorization, the user is redirected to your redirect_uri with a code:

const response = await fetch('https://auth.ontologie-growthsystemes.com/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
grant_type: 'authorization_code',
code: 'CODE_RECU',
redirect_uri: 'https://votre-app.com/callback',
client_id: 'VOTRE_CLIENT_ID',
code_verifier: 'CODE_VERIFIER_ORIGINAL',
}),
});

const { access_token, refresh_token, expires_in } = await response.json();

Step 4: Use the token

Include the token in your API requests:

curl -H "Authorization: Bearer ACCESS_TOKEN" \
-H "x-workspace-id: WORKSPACE_ID" \
"https://api.ontologie-growthsystemes.com/api/queries/nodes"

Step 5: Refresh the token

When the token expires, use the refresh token:

const response = await fetch('https://auth.ontologie-growthsystemes.com/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
grant_type: 'refresh_token',
refresh_token: 'VOTRE_REFRESH_TOKEN',
client_id: 'VOTRE_CLIENT_ID',
}),
});

OAuth scopes

The available scopes are identical to those of API keys:

ScopeDescription
read:nodesRead entities
write:nodesCreate and modify entities
read:edgesRead relations
write:edgesCreate and modify relations
read:livedataRead Live Data sources
write:livedataManage Live Data sources

For the full list, see Permissions.

Security

PracticeDescription
Store tokens securelyUse the browser's secure storage (not localStorage)
Validate the state parameterCompare the returned state with the one sent
Always use PKCENever transmit the code verifier in the URL
Token lifetimeAccess token: 1 hour. Refresh token: 30 days
RevocationRevoke tokens via the /revoke endpoint when a user logs out

With the SDK

The @ontologie/oauth package simplifies the OAuth flow:

import { createOAuthClient } from '@ontologie/oauth';

const oauth = createOAuthClient({
clientId: 'VOTRE_CLIENT_ID',
redirectUri: 'https://votre-app.com/callback',
scopes: ['read:nodes', 'write:nodes'],
});

// Demarrer le flux
const authUrl = await oauth.getAuthorizationUrl();
window.location.href = authUrl;

// Callback : echanger le code
const tokens = await oauth.handleCallback(window.location.search);

See also

Need help?

Contact us: Support and contact.